Merge branch 'astar' into idf-mobilite-net
This commit is contained in:
commit
22bb3a2515
13 changed files with 451 additions and 39 deletions
14
pom.xml
14
pom.xml
|
@ -31,7 +31,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.json</groupId>
|
<groupId>org.json</groupId>
|
||||||
<artifactId>json</artifactId>
|
<artifactId>json</artifactId>
|
||||||
<version>20230618</version>
|
<version>20231013</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
@ -67,6 +67,18 @@
|
||||||
</archive>
|
</archive>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>3.2.5</version>
|
||||||
|
<configuration>
|
||||||
|
<includes>
|
||||||
|
<include>**/*Test.java</include>
|
||||||
|
</includes>
|
||||||
|
<testFailureIgnore>true</testFailureIgnore>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
<resources>
|
<resources>
|
||||||
<resource>
|
<resource>
|
||||||
|
|
|
@ -10,6 +10,7 @@ import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.File;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
@ -77,6 +78,10 @@ public class IDFMNetworkExtractor {
|
||||||
private static final int IDFM_STOPS_LAT_INDEX = 7;
|
private static final int IDFM_STOPS_LAT_INDEX = 7;
|
||||||
private static final int IDFM_URL_INDEX = 10;
|
private static final int IDFM_URL_INDEX = 10;
|
||||||
|
|
||||||
|
private static final String TRACE_FILE_NAME = "trace.csv";
|
||||||
|
|
||||||
|
private static final String HOURS_FILE_NAME = "hours.csv";
|
||||||
|
|
||||||
// Magically chosen values
|
// Magically chosen values
|
||||||
/**
|
/**
|
||||||
* A number of stops on each line
|
* A number of stops on each line
|
||||||
|
@ -225,6 +230,83 @@ public class IDFMNetworkExtractor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean checkFileExistence(String filePath) {
|
||||||
|
File file = new File(filePath);
|
||||||
|
if (file.exists()) {
|
||||||
|
LOGGER.severe(filePath+ " already exists.");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
LOGGER.severe(filePath + " does not exist.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void builFiles() {
|
||||||
|
|
||||||
|
if (checkFileExistence("./"+HOURS_FILE_NAME) && checkFileExistence("./"+TRACE_FILE_NAME)) {
|
||||||
|
LOGGER.severe("Files already exists.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, TraceEntry> traces = new HashMap<>();
|
||||||
|
try {
|
||||||
|
CSVTools.readCSVFromURL(TRACE_FILE_URL,
|
||||||
|
(String[] line) -> addLine(line, traces));
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.log(Level.SEVERE, "Error while reading the line paths", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<StopEntry> stops = new ArrayList<>(traces.size() * GUESS_STOPS_BY_LINE);
|
||||||
|
try {
|
||||||
|
CSVTools.readCSVFromURL(STOPS_FILE_URL,
|
||||||
|
(String[] line) -> addStop(line, traces, stops));
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.log(Level.SEVERE, "Error while reading the stops", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanTraces(traces);
|
||||||
|
|
||||||
|
Map<String, Transport> transports = new HashMap<>();
|
||||||
|
CSVStreamProvider provider = new CSVStreamProvider(traces.values().iterator(), transports);
|
||||||
|
|
||||||
|
// Write into args[0]
|
||||||
|
try {
|
||||||
|
CSVTools.writeCSVToFile(TRACE_FILE_NAME, Stream.iterate(provider.next(),
|
||||||
|
t -> provider.hasNext(), t -> provider.next()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.log(Level.SEVERE, e,
|
||||||
|
() -> MessageFormat.format("Could not write in file {0}", TRACE_FILE_NAME));
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("******************Building bifurcations ************************");
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
for (Transport entry : transports.values()) {
|
||||||
|
entry.buildBifurcationOptimzed();
|
||||||
|
}
|
||||||
|
|
||||||
|
long endTime = System.currentTimeMillis();
|
||||||
|
long tempsPasse = endTime - startTime;
|
||||||
|
|
||||||
|
long minutes = (tempsPasse / 1000) / 60;
|
||||||
|
long seconds = (tempsPasse / 1000) % 60;
|
||||||
|
long milliseconds = tempsPasse % 1000;
|
||||||
|
|
||||||
|
System.out.println("Temps écoulé : " + minutes + " minutess, " + seconds + " secndes et " + milliseconds + " millis");
|
||||||
|
|
||||||
|
System.out.println("******************Fin Building bifurcations ************************");
|
||||||
|
|
||||||
|
CSVSchedulesProvider providerschedules = new CSVSchedulesProvider(transports.values().iterator());
|
||||||
|
try {
|
||||||
|
CSVTools.writeCSVToFile(HOURS_FILE_NAME, Stream.iterate(providerschedules.next(),
|
||||||
|
t -> providerschedules.hasNext(), t -> providerschedules.next()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.log(Level.SEVERE, e,
|
||||||
|
() -> MessageFormat.format("Could not write in file {0}", HOURS_FILE_NAME));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Clean the traces/remove the unresolved lines
|
/** Clean the traces/remove the unresolved lines
|
||||||
* @param traces the traces to clean
|
* @param traces the traces to clean
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package fr.u_paris.gla.project.itinerary;
|
package fr.u_paris.gla.project.itinerary;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
public class Connection{
|
public class Connection{
|
||||||
// Destination of the connection between the two stops
|
// Destination of the connection between the two stops
|
||||||
private final Stop stop;
|
private final Stop stop;
|
||||||
|
@ -7,15 +10,27 @@ public class Connection{
|
||||||
// The line used for this connection
|
// The line used for this connection
|
||||||
private final String lineName;
|
private final String lineName;
|
||||||
|
|
||||||
|
//Distance between the two stops
|
||||||
private final double distance;
|
private final double distance;
|
||||||
|
|
||||||
|
//Travel time between the two stops
|
||||||
private final int time;
|
private final int time;
|
||||||
|
|
||||||
public Connection(Stop stop, String lineName, double distance, int time){
|
private final ArrayList<Integer> schedules;
|
||||||
|
|
||||||
|
private final int bifurcation;
|
||||||
|
|
||||||
|
public Connection(Stop stop, String lineName, double distance, int time, int bifurcation){
|
||||||
this.stop = stop;
|
this.stop = stop;
|
||||||
this.lineName=lineName;
|
this.lineName=lineName;
|
||||||
this.distance = distance;
|
this.distance = distance;
|
||||||
this.time = time;
|
this.time = time;
|
||||||
|
this.schedules = new ArrayList<>();
|
||||||
|
this.bifurcation = bifurcation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Connection(Stop stop, String lineName, double distance, int time){
|
||||||
|
this(stop, lineName, distance, time, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,4 +49,51 @@ public class Connection{
|
||||||
public Stop getStop() {
|
public Stop getStop() {
|
||||||
return stop;
|
return stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addSchedule(int hours) {
|
||||||
|
this.schedules.add(hours);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sortSchedule() {
|
||||||
|
Collections.sort(this.schedules);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Integer> getSchedules() {
|
||||||
|
return this.schedules;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBifurcation() {
|
||||||
|
return this.bifurcation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getCost() {
|
||||||
|
return this.time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getNextTime(double currentTime) {
|
||||||
|
if(this.schedules.size() == 0) {
|
||||||
|
return currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while(i < this.schedules.size() && this.schedules.get(i) < currentTime) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if(i < this.schedules.size()) {
|
||||||
|
return this.schedules.get(i);
|
||||||
|
}
|
||||||
|
return this.schedules.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getCost(double currentTime) {
|
||||||
|
if(this.schedules.size() == 0) {
|
||||||
|
if(this.lineName.equals("WALK")) {
|
||||||
|
return this.time;
|
||||||
|
}
|
||||||
|
return this.time + 900;
|
||||||
|
}
|
||||||
|
double nextTime = this.getNextTime(currentTime);
|
||||||
|
if(nextTime < currentTime) { nextTime += 86400;}
|
||||||
|
return nextTime - currentTime + this.time;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@ public class Finder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Stop> findPath(Stop startNode, Stop goalNode) {
|
public List<Stop> findPath(Stop startNode, Stop goalNode) {
|
||||||
|
double startTime = 43200; //12h
|
||||||
|
|
||||||
PriorityQueue<Stop> openSet = new PriorityQueue<>(Comparator.comparingDouble(GraphNode::getF));
|
PriorityQueue<Stop> openSet = new PriorityQueue<>(Comparator.comparingDouble(GraphNode::getF));
|
||||||
HashSet<Stop> closedSet = new HashSet<>();
|
HashSet<Stop> closedSet = new HashSet<>();
|
||||||
HashMap<Stop, Stop> cameFrom = new HashMap<>();
|
HashMap<Stop, Stop> cameFrom = new HashMap<>();
|
||||||
|
@ -21,16 +23,15 @@ public class Finder {
|
||||||
fScore.put(node, Double.POSITIVE_INFINITY);
|
fScore.put(node, Double.POSITIVE_INFINITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The cost of going from start to start is zero
|
// The cost of going from start to start is the start time
|
||||||
gScore.put(startNode, 0.0);
|
gScore.put(startNode, startTime);
|
||||||
// For the first node, fScore = gScore + heuristic
|
// For the first node, fScore = gScore + heuristic
|
||||||
fScore.put(startNode, startNode.getHeuristicCost(goalNode));
|
fScore.put(startNode, startNode.getHeuristicCost(goalNode));
|
||||||
openSet.add(startNode);
|
openSet.add(startNode);
|
||||||
|
|
||||||
while (!openSet.isEmpty()) {
|
while (!openSet.isEmpty()) {
|
||||||
Stop current = openSet.poll();
|
Stop current = openSet.poll();
|
||||||
//System.out.println(current);
|
double currentTime = gScore.get(current);
|
||||||
//System.out.println(graph.getConnections(current));
|
|
||||||
|
|
||||||
if (current.equals(goalNode)) {
|
if (current.equals(goalNode)) {
|
||||||
return reconstructPath(cameFrom, current);
|
return reconstructPath(cameFrom, current);
|
||||||
|
@ -42,17 +43,15 @@ public class Finder {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Connection connection : graph.getConnections(current) ) {
|
for (Connection connection : graph.getConnections(current)) {
|
||||||
Stop neighbor = connection.getStop();
|
Stop neighbor = connection.getStop();
|
||||||
if (closedSet.contains(neighbor)) {
|
if (closedSet.contains(neighbor)) {
|
||||||
continue; // Ignore the neighbor which is already evaluated.
|
continue; // Ignore the neighbor which is already evaluated.
|
||||||
}
|
}
|
||||||
|
|
||||||
double tentativeGScore = gScore.get(current) + connection.getDistance();
|
double tentativeGScore = currentTime + connection.getCost(currentTime);
|
||||||
|
|
||||||
if (!openSet.contains(neighbor)) {
|
if (tentativeGScore >= gScore.get(neighbor)) {
|
||||||
openSet.add(neighbor);
|
|
||||||
} else if (tentativeGScore >= gScore.get(neighbor)) {
|
|
||||||
continue; // This is not a better path.
|
continue; // This is not a better path.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +59,14 @@ public class Finder {
|
||||||
cameFrom.put(neighbor, current);
|
cameFrom.put(neighbor, current);
|
||||||
gScore.put(neighbor, tentativeGScore);
|
gScore.put(neighbor, tentativeGScore);
|
||||||
fScore.put(neighbor, tentativeGScore + neighbor.getHeuristicCost(goalNode));
|
fScore.put(neighbor, tentativeGScore + neighbor.getHeuristicCost(goalNode));
|
||||||
neighbor.setF(fScore.get(neighbor));
|
|
||||||
|
if (!openSet.contains(neighbor)) {
|
||||||
|
neighbor.setF(fScore.get(neighbor));
|
||||||
|
openSet.add(neighbor);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
updatePriority(openSet, neighbor, fScore.get(neighbor));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,12 +86,16 @@ public class Finder {
|
||||||
return totalPath;
|
return totalPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updatePriority(PriorityQueue<Stop> openSet, Stop node, double newF) {
|
||||||
|
openSet.remove(node);
|
||||||
|
node.setF(newF);
|
||||||
|
openSet.add(node);
|
||||||
|
}
|
||||||
|
|
||||||
//TODO:
|
//TODO:
|
||||||
public List<Stop> findPath(double longitude, double latitude){
|
public List<Stop> findPath(double longitude, double latitude){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,11 @@ public class ItineraryCalculator {
|
||||||
|
|
||||||
private static final double ERROR_MARGIN = 1.;
|
private static final double ERROR_MARGIN = 1.;
|
||||||
|
|
||||||
|
//The time public vehicles spend at each stop in seconds.
|
||||||
|
private static final int STOP_TIME = 30;
|
||||||
|
|
||||||
|
//Walking speed in m/s
|
||||||
|
private static final double WALK_SPEED = 1.;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the coordinates from a String to a double array:
|
* Returns the coordinates from a String to a double array:
|
||||||
|
@ -59,26 +64,40 @@ public class ItineraryCalculator {
|
||||||
* @param lineId the line the stop is on
|
* @param lineId the line the stop is on
|
||||||
* @return the Stop object
|
* @return the Stop object
|
||||||
*/
|
*/
|
||||||
private static Stop getOrCreateStop(HashSet<Stop> nodes, HashMap<String, ArrayList<Stop>> tmp, String name, String gps, String lineId) {
|
private static Stop getOrCreateStop(HashSet<Stop> nodes, HashMap<String, ArrayList<Stop>> tmp, String name, String gps, String lineId, HashMap<Stop, Set<Connection>> connections) {
|
||||||
ArrayList<Stop> stopList = tmp.get(name);
|
ArrayList<Stop> stopList = tmp.get(name);
|
||||||
|
double[] coords = getCoords(gps);
|
||||||
|
|
||||||
// First we search by name, and then compare the coordinates since multiple stations can have the same name. A margin of error is necessary since stops can have multiple GPS coordinates
|
// First we search by name, and then compare the coordinates since multiple stations can have the same name. A margin of error is necessary since stops can have multiple GPS coordinates
|
||||||
|
ArrayList<Stop> lineChanges = new ArrayList<>();
|
||||||
if (stopList != null) {
|
if (stopList != null) {
|
||||||
for(Stop stop : stopList) {
|
for(Stop stop : stopList) {
|
||||||
double[] coords = getCoords(gps);
|
|
||||||
double dist = GPS.distance(coords[0], coords[1], stop.getLatitude(), stop.getLongitude());
|
double dist = GPS.distance(coords[0], coords[1], stop.getLatitude(), stop.getLongitude());
|
||||||
if(dist < ERROR_MARGIN) {
|
if(dist == 0) {
|
||||||
stop.addLine(lineId);
|
stop.addLine(lineId);
|
||||||
return stop;
|
return stop;
|
||||||
}
|
}
|
||||||
|
if(dist < ERROR_MARGIN) {
|
||||||
|
lineChanges.add(stop);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double[] coords = getCoords(gps);
|
|
||||||
Stop newStop = new Stop(lineId, name, coords[0], coords[1]);
|
Stop newStop = new Stop(lineId, name, coords[0], coords[1]);
|
||||||
nodes.add(newStop);
|
nodes.add(newStop);
|
||||||
stopList = stopList == null ? new ArrayList<>() : stopList;
|
stopList = stopList == null ? new ArrayList<>() : stopList;
|
||||||
stopList.add(newStop);
|
stopList.add(newStop);
|
||||||
tmp.put(name, stopList);
|
tmp.put(name, stopList);
|
||||||
|
for(Stop s : lineChanges) {
|
||||||
|
double dist = GPS.distance(coords[0], coords[1], s.getLatitude(), s.getLongitude());
|
||||||
|
int time = (int) (dist*1000/WALK_SPEED);
|
||||||
|
Connection c1 = new Connection(s, "WALK", dist, time);
|
||||||
|
connections.computeIfAbsent(newStop, k -> new HashSet<>()).add(c1);
|
||||||
|
|
||||||
|
Connection c2 = new Connection(newStop, "WALK", dist, time);
|
||||||
|
connections.computeIfAbsent(s, k -> new HashSet<>()).add(c2);
|
||||||
|
}
|
||||||
return newStop;
|
return newStop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,22 +109,107 @@ public class ItineraryCalculator {
|
||||||
* @param connections
|
* @param connections
|
||||||
*/
|
*/
|
||||||
private static void addLine(String[] line, HashSet<Stop> nodes, HashMap<String, ArrayList<Stop>> tmp, HashMap<Stop, Set<Connection>> connections) {
|
private static void addLine(String[] line, HashSet<Stop> nodes, HashMap<String, ArrayList<Stop>> tmp, HashMap<Stop, Set<Connection>> connections) {
|
||||||
Stop fromStop = getOrCreateStop(nodes, tmp, line[IDFM_TRACE_FROM_INDEX], line[IDFM_TRACE_FROM_GPS_INDEX], line[IDFM_TRACE_ID_INDEX]);
|
Stop fromStop = getOrCreateStop(nodes, tmp, line[IDFM_TRACE_FROM_INDEX], line[IDFM_TRACE_FROM_GPS_INDEX], line[IDFM_TRACE_ID_INDEX], connections);
|
||||||
Stop toStop = getOrCreateStop(nodes, tmp, line[IDFM_TRACE_TO_INDEX], line[IDFM_TRACE_TO_GPS_INDEX], line[IDFM_TRACE_ID_INDEX]);
|
Stop toStop = getOrCreateStop(nodes, tmp, line[IDFM_TRACE_TO_INDEX], line[IDFM_TRACE_TO_GPS_INDEX], line[IDFM_TRACE_ID_INDEX], connections);
|
||||||
|
|
||||||
String[] timeString = line[IDFM_TRACE_TIME_INDEX].split(":");
|
String[] timeString = line[IDFM_TRACE_TIME_INDEX].split(":");
|
||||||
int time = Integer.parseInt(timeString[0]) * 60 + Integer.parseInt(timeString[1]);
|
String time0WithoutComma = timeString[0].replace(",", "");
|
||||||
|
int time = Integer.parseInt(time0WithoutComma) * 60 + Integer.parseInt(timeString[1]);
|
||||||
|
|
||||||
Connection connection = new Connection(toStop, line[IDFM_TRACE_ID_INDEX], Double.parseDouble(line[IDFM_TRACE_DISTANCE_INDEX]), time);
|
Connection connection = new Connection(toStop, line[IDFM_TRACE_ID_INDEX], Double.parseDouble(line[IDFM_TRACE_DISTANCE_INDEX]), time, Integer.parseInt(line[IDFM_TRACE_DERIV_INDEX]));
|
||||||
|
|
||||||
connections.computeIfAbsent(fromStop, k -> new HashSet<>()).add(connection);
|
connections.computeIfAbsent(fromStop, k -> new HashSet<>()).add(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void addScheduleRec(Stop current, Stop previous, String line, ArrayList<Integer> bifurcations, int time, HashMap<String, ArrayList<Stop>> stopsHashSet, HashMap<Stop, Set<Connection>> connections, HashSet<Stop> processed){
|
||||||
|
time = time%86400;
|
||||||
|
//If the stop has already been processed, it is not reprocessed.
|
||||||
|
if(processed.contains(current)) {return;}
|
||||||
|
processed.add(current);
|
||||||
|
|
||||||
|
Set<Connection> neighborhood = connections.get(current);
|
||||||
|
if(neighborhood == null) {return;}
|
||||||
|
|
||||||
|
|
||||||
|
ArrayList<Connection> directions = new ArrayList<>();
|
||||||
|
for(Connection n : neighborhood) {
|
||||||
|
if(n.getLineName().equals(line)
|
||||||
|
&& (previous == null || !n.getStop().getName().equals(previous.getName()))
|
||||||
|
) {
|
||||||
|
directions.add(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(directions.size() == 0) {return;}
|
||||||
|
|
||||||
|
Stop next_stop = null;
|
||||||
|
if(directions.size() > 1) {
|
||||||
|
int bifurcation = bifurcations.size() == 0 ? 0 : bifurcations.get(0);
|
||||||
|
if(bifurcations.size() > 0) {bifurcations.remove(0);}
|
||||||
|
for(Connection d : directions) {
|
||||||
|
if(d.getBifurcation() == bifurcation) {
|
||||||
|
next_stop = d.getStop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(next_stop == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
next_stop = directions.get(0).getStop();
|
||||||
|
if(directions.get(0).getBifurcation() != 0) {
|
||||||
|
if(bifurcations.size() > 0 && directions.get(0).getBifurcation() == bifurcations.get(0)){
|
||||||
|
bifurcations.remove(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Connection n : neighborhood) {
|
||||||
|
if(n.getStop() == next_stop) {
|
||||||
|
n.addSchedule(time);
|
||||||
|
time += n.getTime();
|
||||||
|
addScheduleRec(next_stop, current, line, bifurcations, time, stopsHashSet, connections, processed);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addSchedule(String[] input, HashMap<String, ArrayList<Stop>> stopsHashSet, HashMap<Stop, Set<Connection>> connections) {
|
||||||
|
|
||||||
|
String line = input[0];
|
||||||
|
|
||||||
|
ArrayList<Integer> bifurcations = new ArrayList<>();
|
||||||
|
if(!input[1].equals("[]")) {
|
||||||
|
String[] b = input[1].substring(1, input[1].length()-1).split(",");
|
||||||
|
bifurcations = new ArrayList<>();
|
||||||
|
for(String n : b){
|
||||||
|
bifurcations.add(Integer.parseInt(n.trim()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String name = input[2];
|
||||||
|
|
||||||
|
String[] timeString = input[3].split(":");
|
||||||
|
int time = Integer.parseInt(timeString[0]) * 3600 + Integer.parseInt(timeString[1])*60 + STOP_TIME;
|
||||||
|
|
||||||
|
|
||||||
|
ArrayList<Stop> stops = stopsHashSet.get(name);
|
||||||
|
if(stops == null) {return;}
|
||||||
|
|
||||||
|
for(Stop stop : stops) {
|
||||||
|
if(stop.getLines().contains(line)) {
|
||||||
|
addScheduleRec(stop, null, line, bifurcations, time, stopsHashSet, connections, new HashSet<>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args){
|
public static void main(String[] args){
|
||||||
if (args.length != 0) {
|
if (args.length != 0) {
|
||||||
LOGGER.severe("Invalid command line. Target file names are in the main file for now.");
|
LOGGER.severe("Invalid command line. Target file names are in the main file for now.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
IDFMNetworkExtractor.builFiles();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
HashSet<Stop> nodes = new HashSet<>();
|
HashSet<Stop> nodes = new HashSet<>();
|
||||||
|
@ -114,6 +218,15 @@ public class ItineraryCalculator {
|
||||||
CSVTools.readCSVFromFile(TRACE_FILE_NAME,
|
CSVTools.readCSVFromFile(TRACE_FILE_NAME,
|
||||||
(String[] line) -> addLine(line, nodes, tmp, connections));
|
(String[] line) -> addLine(line, nodes, tmp, connections));
|
||||||
|
|
||||||
|
CSVTools.readCSVFromFile(HOURS_FILE_NAME,
|
||||||
|
(String[] line) -> addSchedule(line, tmp, connections));
|
||||||
|
|
||||||
|
for(Set<Connection> set : connections.values()) {
|
||||||
|
for(Connection c : set) {
|
||||||
|
c.sortSchedule();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Stop porteivry = tmp.get("Porte d'Ivry").get(0);
|
Stop porteivry = tmp.get("Porte d'Ivry").get(0);
|
||||||
Stop repu = tmp.get("République").get(0);
|
Stop repu = tmp.get("République").get(0);
|
||||||
|
@ -132,7 +245,6 @@ public class ItineraryCalculator {
|
||||||
Finder finder = new Finder(graph);
|
Finder finder = new Finder(graph);
|
||||||
|
|
||||||
List<Stop> res = finder.findPath(porteivry, chatelet);
|
List<Stop> res = finder.findPath(porteivry, chatelet);
|
||||||
|
|
||||||
for (Stop element : res) {
|
for (Stop element : res) {
|
||||||
System.out.println(element);
|
System.out.println(element);
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,4 +85,6 @@ public class Stop implements GraphNode {
|
||||||
public void addLine(String s){
|
public void addLine(String s){
|
||||||
lines.add(s);
|
lines.add(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<String> getLines() { return this.lines; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import org.junit.jupiter.api.Test;
|
||||||
class AppTest {
|
class AppTest {
|
||||||
/** Rigorous Test :-) */
|
/** Rigorous Test :-) */
|
||||||
@Test
|
@Test
|
||||||
void testPlaceholder() {
|
public void testPlaceholder() {
|
||||||
assertTrue(true, "It should be true that true is true...");
|
assertTrue(true, "It should be true that true is true...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
68
src/test/java/fr/u_paris/gla/project/idfm/StopTest.java
Normal file
68
src/test/java/fr/u_paris/gla/project/idfm/StopTest.java
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
package fr.u_paris.gla.project.idfm;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
public class StopTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsStopConnected() {
|
||||||
|
|
||||||
|
Stop stop = new Stop("Stop1");
|
||||||
|
BifStop bifStop1 = new BifStop(1, new Stop("Stop2"));
|
||||||
|
// Initially, no stops are connected
|
||||||
|
assertFalse(stop.isStopConnected("Stop2"));
|
||||||
|
|
||||||
|
// Add a connected stop
|
||||||
|
stop.addConnectedStop(bifStop1);
|
||||||
|
|
||||||
|
// Now, Stop2 should be connected
|
||||||
|
assertTrue(stop.isStopConnected("Stop2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetConnectedStop() {
|
||||||
|
|
||||||
|
Stop stop = new Stop("Stop1");
|
||||||
|
BifStop bifStop1 = new BifStop(1, new Stop("Stop2"));
|
||||||
|
BifStop bifStop2 = new BifStop(2, new Stop("Stop3"));
|
||||||
|
|
||||||
|
// Add two connected stops
|
||||||
|
stop.addConnectedStop(bifStop1);
|
||||||
|
stop.addConnectedStop(bifStop2);
|
||||||
|
|
||||||
|
// Retrieve the connected stops
|
||||||
|
BifStop retrievedStop1 = stop.getConnectedStop("Stop2");
|
||||||
|
BifStop retrievedStop2 = stop.getConnectedStop("Stop3");
|
||||||
|
|
||||||
|
// Check if the correct stops were retrieved
|
||||||
|
assertEquals(bifStop1, retrievedStop1);
|
||||||
|
assertEquals(bifStop2, retrievedStop2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddConnectedStop() {
|
||||||
|
Stop stop = new Stop("Stop1");
|
||||||
|
BifStop bifStop1 = new BifStop(1, new Stop("Stop2"));
|
||||||
|
|
||||||
|
// Add a connected stop
|
||||||
|
stop.addConnectedStop(bifStop1);
|
||||||
|
|
||||||
|
// Check if the stop was added
|
||||||
|
assertTrue(stop.isStopConnected("Stop2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSHJH(){
|
||||||
|
Stop stop = new Stop("Stop2323");
|
||||||
|
BifStop bifStop1 = new BifStop(1, new Stop("Stop2323"));
|
||||||
|
|
||||||
|
// Add a connected stop
|
||||||
|
stop.addConnectedStop(bifStop1);
|
||||||
|
|
||||||
|
// Check if the stop was added
|
||||||
|
assertTrue(stop.isStopConnected("Stop2323"));
|
||||||
|
}
|
||||||
|
}
|
64
src/test/java/fr/u_paris/gla/project/idfm/TransportTest.java
Normal file
64
src/test/java/fr/u_paris/gla/project/idfm/TransportTest.java
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
package fr.u_paris.gla.project.idfm;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import java.util.AbstractMap.SimpleEntry;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
public class TransportTest {
|
||||||
|
|
||||||
|
/*@Test
|
||||||
|
public void testRoadToLast() {
|
||||||
|
Transport transport = new Transport("Test Line", "Bus");
|
||||||
|
transport.addStop("A", "B", 1);
|
||||||
|
transport.addStop("B", "C", 2);
|
||||||
|
transport.addStop("C", "D", 3);
|
||||||
|
TraceDescription td = new TraceDescription("A", "D", "A", "D");
|
||||||
|
transport.descriptions.add(td);
|
||||||
|
|
||||||
|
List<String> visited = new ArrayList<>();
|
||||||
|
List<Integer> bifurcations = new ArrayList<>();
|
||||||
|
SimpleEntry<Boolean, List<Integer>> result = transport.roadToLast("A", "D", visited, bifurcations);
|
||||||
|
assertFalse(result.getKey());
|
||||||
|
assertEquals(List.of(1, 2, 3), result.getValue());
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*@Test
|
||||||
|
public void testRoadToLastOptimized() {
|
||||||
|
SimpleEntry<Boolean, List<Integer>> result = transport.roadToLastOptimized("A", "D", new HashSet<>(), new ArrayList<>());
|
||||||
|
assertTrue(result.getKey());
|
||||||
|
assertEquals(List.of(1, 2, 3), result.getValue());
|
||||||
|
}*/
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsTerminus() {
|
||||||
|
Transport transport = new Transport("Test Line", "Bus");
|
||||||
|
transport.addStop("A", "B", 1);
|
||||||
|
transport.addStop("B", "C", 2);
|
||||||
|
transport.addStop("C", "D", 3);
|
||||||
|
TraceDescription td = new TraceDescription("A", "D", "A", "D");
|
||||||
|
transport.descriptions.add(td);
|
||||||
|
|
||||||
|
assertTrue(transport.isTerminus("A"));
|
||||||
|
assertTrue(transport.isTerminus("D"));
|
||||||
|
assertFalse(transport.isTerminus("B"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddStop() {
|
||||||
|
Transport transport = new Transport("Test Line", "Bus");
|
||||||
|
transport.addStop("A", "B", 1);
|
||||||
|
transport.addStop("B", "C", 2);
|
||||||
|
transport.addStop("C", "D", 3);
|
||||||
|
TraceDescription td = new TraceDescription("A", "D", "A", "D");
|
||||||
|
transport.descriptions.add(td);
|
||||||
|
|
||||||
|
transport.addStop("D", "E", 4);
|
||||||
|
assertTrue(transport.stopsMap.containsKey("E"));
|
||||||
|
assertEquals("E", transport.stopsMap.get("E").name);
|
||||||
|
assertTrue(transport.stopsMap.get("D").isStopConnected("E"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,30 +17,30 @@ class NetworkFormatTest {
|
||||||
NumberFormat GPS_test = NetworkFormat.getGPSFormatter();
|
NumberFormat GPS_test = NetworkFormat.getGPSFormatter();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void parseDurationEqual() {
|
public void testParseDurationEqual() {
|
||||||
|
|
||||||
assertEquals(Duration.ZERO, NetworkFormat.parseDuration(t));
|
assertEquals(Duration.ZERO, NetworkFormat.parseDuration(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void parseDurationTooBig() {
|
public void testParseDurationTooBig() {
|
||||||
String y = "119:00";
|
String y = "119:00";
|
||||||
assertThrows(DateTimeParseException.class, () -> NetworkFormat.parseDuration(y));
|
assertThrows(DateTimeParseException.class, () -> NetworkFormat.parseDuration(y));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void formatDuration() {
|
public void formatDuration() {
|
||||||
assertEquals(t, NetworkFormat.formatDuration(Duration.ZERO));
|
assertEquals(t, NetworkFormat.formatDuration(Duration.ZERO));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void parseThenFormatDuration(){
|
public void parseThenFormatDuration(){
|
||||||
String t = "00:00";
|
String t = "00:00";
|
||||||
assertEquals(t, NetworkFormat.formatDuration(NetworkFormat.parseDuration(t)));
|
assertEquals(t, NetworkFormat.formatDuration(NetworkFormat.parseDuration(t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void getGPSFormatterPos() {
|
public void getGPSFormatterPos() {
|
||||||
double GPS_pos = 1.456489615649813;
|
double GPS_pos = 1.456489615649813;
|
||||||
assertEquals(String.valueOf(GPS_pos), GPS_test.format(GPS_pos));
|
assertEquals(String.valueOf(GPS_pos), GPS_test.format(GPS_pos));
|
||||||
|
|
||||||
|
@ -48,14 +48,14 @@ class NetworkFormatTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void getGPSFormatterNeg() {
|
public void getGPSFormatterNeg() {
|
||||||
double GPS_neg = -1.456489615649813;
|
double GPS_neg = -1.456489615649813;
|
||||||
assertEquals(String.valueOf(GPS_neg), GPS_test.format(GPS_neg));
|
assertEquals(String.valueOf(GPS_neg), GPS_test.format(GPS_neg));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
void getGPSFormatterNul() {
|
public void getGPSFormatterNul() {
|
||||||
int GPS_nul = 0;
|
int GPS_nul = 0;
|
||||||
assertEquals(String.valueOf(GPS_nul), GPS_test.format(GPS_nul));
|
assertEquals(String.valueOf(GPS_nul), GPS_test.format(GPS_nul));
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ class NetworkFormatTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void getGPSFormatterBig() {
|
public void getGPSFormatterBig() {
|
||||||
String string_int = "4565156498156489";
|
String string_int = "4565156498156489";
|
||||||
String string_float = "5675747274674276474267479751262167";
|
String string_float = "5675747274674276474267479751262167";
|
||||||
BigDecimal GPS_big = new BigDecimal(string_int + "." + string_float);
|
BigDecimal GPS_big = new BigDecimal(string_int + "." + string_float);
|
||||||
|
|
|
@ -21,7 +21,7 @@ class ScheduleFormatTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void getTimeFormatter() {
|
public void getTimeFormatter() {
|
||||||
DateTimeFormatter formatter = ScheduleFormat.getTimeFormatter();
|
DateTimeFormatter formatter = ScheduleFormat.getTimeFormatter();
|
||||||
LocalDateTime date = LocalDateTime.now();
|
LocalDateTime date = LocalDateTime.now();
|
||||||
String test = date.format(formatter);
|
String test = date.format(formatter);
|
||||||
|
|
|
@ -17,7 +17,7 @@ class CSVToolsTest {
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void readCSVFromURL_invalid() {
|
public void readCSVFromURL_invalid() {
|
||||||
// TODO Fix the exception thrown
|
// TODO Fix the exception thrown
|
||||||
/**
|
/**
|
||||||
assertThrows(IOException.class,() -> {
|
assertThrows(IOException.class,() -> {
|
||||||
|
@ -31,7 +31,7 @@ class CSVToolsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void readCSVFromURL_valid() {
|
public void testreadCSVFromURL_valid() {
|
||||||
assertDoesNotThrow(() -> {
|
assertDoesNotThrow(() -> {
|
||||||
Consumer<String[]> test = s -> System.out.println(Arrays.toString(s));
|
Consumer<String[]> test = s -> System.out.println(Arrays.toString(s));
|
||||||
CSVTools.readCSVFromURL("https://people.sc.fsu.edu/~jburkardt/data/csv/addresses.csv",
|
CSVTools.readCSVFromURL("https://people.sc.fsu.edu/~jburkardt/data/csv/addresses.csv",
|
||||||
|
|
|
@ -8,7 +8,7 @@ class GPSTest {
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void distance_SameLat(){
|
public void testDistance_SameLat(){
|
||||||
assertDoesNotThrow(
|
assertDoesNotThrow(
|
||||||
() -> {
|
() -> {
|
||||||
GPS.distance(5, 3, 5, 11);
|
GPS.distance(5, 3, 5, 11);
|
||||||
|
@ -17,7 +17,7 @@ class GPSTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void distance_SameLon(){
|
public void distance_SameLon(){
|
||||||
assertDoesNotThrow(
|
assertDoesNotThrow(
|
||||||
() -> {
|
() -> {
|
||||||
GPS.distance(5, 3, 7, 3);
|
GPS.distance(5, 3, 7, 3);
|
||||||
|
@ -26,12 +26,12 @@ class GPSTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void distance_SamePoint() {
|
public void distance_SamePoint() {
|
||||||
assertEquals(0.0, GPS.distance(5, 3, 5, 3) );
|
assertEquals(0.0, GPS.distance(5, 3, 5, 3) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void distance_NegativePoint(){
|
public void distance_NegativePoint(){
|
||||||
assertNotEquals(0.0, GPS.distance(-5, 7, -13, 4));
|
assertNotEquals(0.0, GPS.distance(-5, 7, -13, 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue