added images and commented code

Questo commit è contenuto in:
Lacroix Raphael 2022-05-28 13:30:51 +02:00
parent f023a2ae70
commit 47150a44b1
14 ha cambiato i file con 311 aggiunte e 70 eliminazioni

77
DeLorean.java File normale
Vedi file

@ -0,0 +1,77 @@
// pseudo code du rapport sur le problme ouvert
public class DeLoreanShortestPath extends ShortestPathAlgorithm {
public DijkstraAlgorithm(ShortestPathData data) {
super(data);
}
ShortestPathSolution solution;
// on pourra par exemple mettre le graphe des stations dans data
final ShortestPathData data = getInputData();
Graph gr = data.getGraph();
StationGraph grS = data.getStationGraph();
double maximumDist = ... //(ici 200000, on pourrait passer cette variable dans data puisque certains voitures n'auront pas la même autonomie)
/*On part du principe ici que le coût en temps prend déjà en compte les 10 minutes de rechargement. Il suffirait si ce n'est pas le cas de regarder si la destination de l'arc est la destination finale et si ce n'est pas le cas de rajouter 10 au coût temporel*/
// on récupère la destination et l'origine
NodeStation nodeA = getNodeStationFromNode(...)
NodeStation nodeB = getNodeStationFromNode(...)
//On récupère la liste des nodes correspondantes aux stations (stockée dans notre graphe des stations).
arrayList<NodeStation> list = getNodeStationsFromNode(...)
/*
int UpdateGraphIsodistance(Node,double,Graph)
est une méthode de la classe StationGraph qui met à jour le StationGraph par rapport à l'Isodistance autour de A dans le graphe graph. Elle renvoie le nombre d'arrêtes crées (-1 si aucune).*/
// on calcule l'Isodistance de A
if (grS.UpdateIsodistance(NodeA,maximumDist,gr) != -1){
// A.hasSuccessor(B) itère sur les successeurs d'un NodeStation (A) et vérifie si l'un d'entre eux est B
if(!NodeA.hasSuccessor(NodeB)){
// on calcule l'Isodistance de B
if (grS.UpdateIsodistance(NodeB,maximumDist,gr) != -1){
/*StationAStarAlgorithm(ShortestPathData, double) hérite de AStar et ne fait que s'adapter aux classes "Station" pour rechercher quel est le plus court chemin sur le graphe des stations*/
StationAStarAlgorithm AAlgo = new StationAStarAlgorithm(data);
StationPath aStarResult = AAlgo.doRun();
arrayList<ArcStation> way = aStarResult.getStationArc();
Path[] pathArray = new Path[way.size()];
int i = 0;
for(ArcStation i : way){
if (data.getMode() == AbstractInputData.Mode.TIME) {
pathArray[i] = way.getTimePath()
// à noter qu'on pourrait également retourner le path renvoyé par un ModifiedAStarAlgorithm lancé en temps si le choix a été fait de ne pas stocker dans les arc le chemin correspondant.
} else {
pathArray[i] = way.getLengthPath()
}
}
// à noter également que si l'on choisit de stocker des listes d'Arc plutôt que des Path il suffira de faire remplacer le Path.concatenate(...) par un new Path(gr, arcs)
// il nous faut maintenant concaténer les chemins entre chaque station
solution = new ShortestPathSolution(data, AbstractSolution.Status.OPTIMAL, Path.concatenate(pathArray));
} else {
// aucune solution car aucune NodeS dans l'isodistance de B
solution = new ShortestPathSolution(data, AbstractSolution.Status.INFEASIBLE);
}
} else {
/*ModifiedAStarAlgorithm(ShortestPathData, double) hérite de AStar et ne change que le fait qu'un arc n'est inséré que si son coût depuis l'origine est inférieur à la valeur passée en argument du constructeur */
// pas besoin de stations car B est dans l'isodistance de A
ModifiedAStarAlgorithm AAlgo = new ModifiedAStarAlgorithm(data, maximumDist);
solution = AAlgo.doRun();
}
} else {
// aucune solution car aucune NodeS dans l'isodistance de A
solution = new ShortestPathSolution(data, AbstractSolution.Status.INFEASIBLE);
}
}

BIN
UML1.png File normale

File binario non mostrato.

Dopo

Larghezza:  |  Altezza:  |  Dimensione: 117 KiB

BIN
UML2.png File normale

File binario non mostrato.

Dopo

Larghezza:  |  Altezza:  |  Dimensione: 147 KiB

Vedi file

@ -23,5 +23,22 @@
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="src" path="target/generated-sources/annotations">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="m2e-apt" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="m2e-apt" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/> <classpathentry kind="output" path="target/classes"/>
</classpath> </classpath>

Vedi file

@ -19,15 +19,23 @@ public class AStarAlgorithm extends DijkstraAlgorithm {
super(data); super(data);
} }
// only difference with Dijkstra : using different labels
@Override @Override
protected void initLabel(){ protected void initLabel(){
int i = 0; int i = 0;
// usefull for the estimated crowlength time,
// if there are no maximal speed we use 130 km/h
double maxSpeed = 130; double maxSpeed = 130;
if (data.getMode() == AbstractInputData.Mode.TIME){ if (data.getMode() == AbstractInputData.Mode.TIME){
if (gr.getGraphInformation().hasMaximumSpeed()){ if (gr.getGraphInformation().hasMaximumSpeed()){
maxSpeed = gr.getGraphInformation().getMaximumSpeed(); maxSpeed = gr.getGraphInformation().getMaximumSpeed();
} }
} }
// initialization close to Dijkstra's
for (Node l : gr.getNodes()){ for (Node l : gr.getNodes()){
if (data.getMode() == AbstractInputData.Mode.TIME){ if (data.getMode() == AbstractInputData.Mode.TIME){
labels[i] = new LabelStar(l, false, null,data.getDestination(), maxSpeed); labels[i] = new LabelStar(l, false, null,data.getDestination(), maxSpeed);

Vedi file

@ -15,15 +15,22 @@ import java.util.List;
public class DijkstraAlgorithm extends ShortestPathAlgorithm { public class DijkstraAlgorithm extends ShortestPathAlgorithm {
/* === Used for testing purposes ===
private long nodes = 0;
*/
public DijkstraAlgorithm(ShortestPathData data) { public DijkstraAlgorithm(ShortestPathData data) {
super(data); super(data);
} }
final ShortestPathData data = getInputData(); final ShortestPathData data = getInputData();
Graph gr = data.getGraph(); Graph gr = data.getGraph();
// array containing all the labels // array containing all the labels
Label[] labels = new Label[gr.size()]; Label[] labels = new Label[gr.size()];
// initialization (separate so that it can be overridden by the A*)
protected void initLabel(){ protected void initLabel(){
int i = 0; int i = 0;
for (Node l : gr.getNodes()){ for (Node l : gr.getNodes()){
@ -45,27 +52,41 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
// initialization of the heap & the first node // initialization of the heap & the first node
BinaryHeap<Label> pQueue = new BinaryHeap<Label>(); BinaryHeap<Label> pQueue = new BinaryHeap<Label>();
labels[data.getOrigin().getId()].setCost(0); labels[data.getOrigin().getId()].setCost(0);
pQueue.insert(labels[data.getOrigin().getId()]); pQueue.insert(labels[data.getOrigin().getId()]);
boolean found = false; boolean found = false;
/*double prev = 0;*/ /* === Used for testing purposes ===
// Pathfinding double prev = 0;
*/
// Pathfinding : we iterate while there are still nodes
// to find and we have not found the destination yet
while(!pQueue.isEmpty() && !found){ while(!pQueue.isEmpty() && !found){
Label labelX = pQueue.deleteMin(); Label labelX = pQueue.deleteMin();
/*if (labelX.getCost()<prev){System.out.println(labelX.getCost()-prev);} /* === Used for testing purposes ===
prev = labelX.getCost();*/ if (labelX.getCost()<prev){System.out.println(labelX.getCost()-prev);}
prev = labelX.getCost();
*/
/* === Used for testing purposes ===
nodes++;
*/
labelX.setMarked(true); labelX.setMarked(true);
notifyNodeReached(labelX.getCurrNode()); notifyNodeReached(labelX.getCurrNode()); // displaying function
found = (data.getDestination() == labelX.getCurrNode());
for (Arc y : labelX.getCurrNode().getSuccessors()){ found = (data.getDestination() == labelX.getCurrNode()); // check for destination reaching
for (Arc y : labelX.getCurrNode().getSuccessors()){ // iterate over all the successors
Label labelY = labels[y.getDestination().getId()]; Label labelY = labels[y.getDestination().getId()];
if (!labelY.isMarked() && data.isAllowed(y)){
if (!labelY.isMarked() && data.isAllowed(y)){ // check for path types
if (labelY.getCost() > labelX.getCost()+data.getCost(y)){ if (labelY.getCost() > labelX.getCost()+data.getCost(y)){
// updating the label with a better cost
if (labels[labelY.getCurrNode().getId()].getCost() != Double.POSITIVE_INFINITY) { if (labels[labelY.getCurrNode().getId()].getCost() != Double.POSITIVE_INFINITY) {
pQueue.remove(labelY); pQueue.remove(labelY);
} }
@ -81,7 +102,7 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
ShortestPathSolution solution = null; ShortestPathSolution solution = null;
// Destination has no predecessor, the solution is infeasible... // Destination has no predecessor, the solution is infeasible...
if (!found || labels[data.getDestination().getId()] == null) { if (!found || labels[data.getDestination().getId()] == null || data.getDestination().getId()==data.getOrigin().getId()) {
solution = new ShortestPathSolution(data, AbstractSolution.Status.INFEASIBLE); solution = new ShortestPathSolution(data, AbstractSolution.Status.INFEASIBLE);
} }
else { else {
@ -103,7 +124,9 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
// Create the final solution. // Create the final solution.
solution = new ShortestPathSolution(data, AbstractSolution.Status.OPTIMAL, new Path(gr, arcs)); solution = new ShortestPathSolution(data, AbstractSolution.Status.OPTIMAL, new Path(gr, arcs));
} }
/* === Used for testing purposes ===
System.out.print(" ... number of nodes : "+nodes);
*/
return solution; return solution;
} }

Vedi file

@ -148,7 +148,8 @@ public class BinaryHeap<E extends Comparable<E>> implements PriorityQueue<E> {
public void remove(E x) throws ElementNotFoundException { public void remove(E x) throws ElementNotFoundException {
/* LEGACY CODE : /* LEGACY CODE :
Index of is not optimized but it's better than nothing. We will come back to improve it if we have time at the end Index of is not optimized but it's better than nothing. We will come back to improve it if we have time at the end
int i = this.array.indexOf(x) */ int i = this.array.indexOf(x);
*/
int i = -1; int i = -1;
@ -164,8 +165,13 @@ public class BinaryHeap<E extends Comparable<E>> implements PriorityQueue<E> {
if (i > this.currentSize - 1 || i == -1) { if (i > this.currentSize - 1 || i == -1) {
throw new ElementNotFoundException(x); throw new ElementNotFoundException(x);
} }
// we decrement the index of the last element and set our value to be after this one
E lastItem = this.array.get(--this.currentSize); E lastItem = this.array.get(--this.currentSize);
this.arraySet(i, lastItem); this.arraySet(i, lastItem);
// need to update the heap
this.percolateDown(i); this.percolateDown(i);
this.percolateUp(i); this.percolateUp(i);

Vedi file

@ -28,5 +28,22 @@
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="src" path="target/generated-sources/annotations">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="m2e-apt" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="m2e-apt" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/> <classpathentry kind="output" path="target/classes"/>
</classpath> </classpath>

Vedi file

@ -22,10 +22,15 @@ import org.insa.graphs.model.io.GraphReader;
import org.insa.graphs.model.io.PathReader; import org.insa.graphs.model.io.PathReader;
// for colouring // for colouring
import java.time.Duration;
import java.util.Random; import java.util.Random;
import java.awt.Color; import java.awt.Color;
import java.util.concurrent.TimeUnit;
public class Launch { public class Launch {
private static int verbose = 1;
private static long timeA = 0;
private static long timeD = 0;
/** /**
@ -52,6 +57,8 @@ public class Launch {
return basicDrawing; return basicDrawing;
} }
// generates a path with the chosen algorithm
public static Path createTestPath(Graph graph,int idOrigin,int idDest,String algo){ public static Path createTestPath(Graph graph,int idOrigin,int idDest,String algo){
Node A = graph.get(idOrigin); Node A = graph.get(idOrigin);
Node B = graph.get(idDest); Node B = graph.get(idDest);
@ -60,31 +67,37 @@ public class Launch {
ShortestPathSolution sol; ShortestPathSolution sol;
ShortestPathData data= new ShortestPathData(graph,A,B,ins); ShortestPathData data= new ShortestPathData(graph,A,B,ins);
switch (algo){ switch (algo){ // we chose the algo we want
case "A*": case "A*":
AStarAlgorithm AAlgo = new AStarAlgorithm(data); AStarAlgorithm AAlgo = new AStarAlgorithm(data);
sol = AAlgo.doRun(); sol = AAlgo.doRun();
resu = sol.getPath(); resu = sol.getPath();
break; break;
case "D": case "D":
DijkstraAlgorithm DAlgo = new DijkstraAlgorithm(data); DijkstraAlgorithm DAlgo = new DijkstraAlgorithm(data);
sol = DAlgo.doRun(); sol = DAlgo.doRun();
resu = sol.getPath(); resu = sol.getPath();
break; break;
case "BF": case "BF":
BellmanFordAlgorithm BF = new BellmanFordAlgorithm(data); BellmanFordAlgorithm BF = new BellmanFordAlgorithm(data);
sol = BF.doRun(); sol = BF.doRun();
resu = sol.getPath(); resu = sol.getPath();
break; break;
default: default:
System.out.println("no known algorithm"); if (verbose == 1) { System.out.println("no known algorithm");}
break; break;
} }
return resu; return resu;
} }
public static int comparePath(Path p1, Path p2,boolean time){ public static int comparePath(Path p1, Path p2,boolean time){
// true if both are null or if they have
// - the same time cost
// - the same length
if (p1 == null){ if (p1 == null){
if (p2 == null){ if (p2 == null){
return 1; return 1;
@ -96,66 +109,102 @@ public class Launch {
return 0; return 0;
} }
} }
if(time)
if (Double.compare(p1.getMinimumTravelTime(),p2.getMinimumTravelTime())==0) {
if(time) {
if (Double.compare(p1.getMinimumTravelTime(), p2.getMinimumTravelTime()) == 0) {
return 1; return 1;
} } else {
else
{
return 0; return 0;
} }
else }else{
if (Float.compare(p1.getLength(),p2.getLength())==0) { if (Float.compare(p1.getLength(), p2.getLength()) == 0) {
return 1; return 1;
} } else {
else
{
return 0; return 0;
} }
}
}
private static void displayResult(String algo, int justeD, int nbTest, long time){
if (verbose == 1) {
System.out.println(
algo + " : number of good tests : " + Integer.toString(justeD) + "/"
+ Integer.toString(nbTest * 2) + ". Total execution time : " + Long.toString(time) + "ms");
}
} }
private static int test(Graph graph, String testType,Drawing drawing, int id1, int id2){
private static int test(Graph graph, String testType,Drawing drawing){
int Id1 = (int) Math.floor(Math.random()*graph.size());
int Id2 = (int) Math.floor(Math.random()*graph.size());
int resu = 0; int resu = 0;
System.out.println("testing with nodes " + Id1 + " and " + Id2); long endTime;
if (comparePath(createTestPath(graph, Id1, Id2, testType),createTestPath(graph, Id1, Id2, "BF"), true) == 0) { long startTime;
resu++; if (verbose == 1) { System.out.print("testing " + testType +" with nodes " + id1 + " and " + id2);}
Path pathAlgo = null;
if (testType == "A*"){
// times the run of the algorithm
startTime = System.currentTimeMillis();
pathAlgo = createTestPath(graph, id1, id2, "A*");
endTime = System.currentTimeMillis();
if (verbose == 2){System.out.println(endTime-startTime);}
timeA += (endTime-startTime);
} else {
// times the run of the algorithm
startTime = System.currentTimeMillis();
pathAlgo = createTestPath(graph, id1, id2, "D");
endTime = System.currentTimeMillis();
timeD += (endTime-startTime);
if (verbose == 2){if (pathAlgo != null) {System.out.print(pathAlgo.getLength()+","+(endTime-startTime) + ",");}}
} }
else
{ Path pathBF = createTestPath(graph, id1, id2, "BF");
// tests if the results are the same in terms of time and length
if (comparePath(pathAlgo, pathBF, true) == 1) {
resu++; resu++;
} }
if (comparePath(createTestPath(graph, Id1, Id2, "D"),createTestPath(graph, Id1, Id2, "BF"), false) == 0) { if (comparePath(pathAlgo, pathBF,false) == 1) {
resu++; resu++;
} }
else
{ // draw the path created on the map (purely visual)
resu++; Path drawPath = pathAlgo;
}
Path drawPath = createTestPath(graph, Id1, Id2, "BF");
if (drawPath != null){ if (drawPath != null){
if (!drawPath.isEmpty()){ if (!drawPath.isEmpty()){
try {
Random rand = new Random(); if (testType == "A*") {
float r = rand.nextFloat(); drawing.drawPath(drawPath, new Color(150, 0, 150));
float g = rand.nextFloat(); } else {
float b = rand.nextFloat(); drawing.drawPath(drawPath, new Color(20, 200, 20));
drawing.drawPath(drawPath,new Color(r, g, b)); }
} catch (Exception e) {}
if (verbose == 1) { System.out.println(" ... Done (length : " + Float.toString(drawPath.getLength()) + " found in " + Long.toString(endTime-startTime) + " ms)");}
} }
} }
return resu; return resu;
} }
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
// Visit these directory to see the list of available files on Commetud. // Visit these directory to see the list of available files on Commetud.
final String mapName = "/home/rlacroix/Bureau/3MIC/Be Graphe/mapinsa/insa.mapgr"; //final String mapName = "/home/rlacroix/Bureau/3MIC/Be Graphe/mapinsa/insa.mapgr";
//final String mapName = "/home/rlacroix/Bureau/3MIC/Be Graphe/mapinsa/carre-dense.mapgr";
final String mapName = "/home/rlacroix/Bureau/3MIC/Be Graphe/mapinsa/california.mapgr";
//final String pathName = "/home/rlacroix/Bureau/3MIC/Be Graphe/mapinsa/path_fr31insa_rangueil_r2.path"; //final String pathName = "/home/rlacroix/Bureau/3MIC/Be Graphe/mapinsa/path_fr31insa_rangueil_r2.path";
// Create a graph reader. // Create a graph reader.
@ -171,6 +220,8 @@ public class Launch {
// TODO: Draw the graph on the drawing. // TODO: Draw the graph on the drawing.
drawing.drawGraph(graph); drawing.drawGraph(graph);
// TODO: Create a PathReader. // TODO: Create a PathReader.
//final PathReader pathReader = new BinaryPathReader( //final PathReader pathReader = new BinaryPathReader(
// new DataInputStream(new BufferedInputStream(new FileInputStream(pathName)))); // new DataInputStream(new BufferedInputStream(new FileInputStream(pathName))));
@ -181,20 +232,35 @@ public class Launch {
// TODO: Draw the path. // TODO: Draw the path.
//drawing.drawPath(path); //drawing.drawPath(path);
System.out.println("==TESTS==");
int nbTest = 10000; int nbTest = 2000;
int juste = 0; int justeD = 0;
int justeA = 0;
if (verbose == 1) { System.out.println("== LAUNCHING " + nbTest + " TESTS ==");}
for (int i = 0; i < nbTest; i++){ for (int i = 0; i < nbTest; i++){
// picks two nodes at random
int id1 = (int) Math.floor(Math.random()*graph.size());
int id2 = (int) Math.floor(Math.random()*graph.size());
if (i%10 == 0){ if (i%10 == 0){
// cleans the board every 10 runs and display the comparative runtimes
drawing.clearOverlays(); drawing.clearOverlays();
displayResult("Dijkstra",justeD,i,timeD);
displayResult("A*",justeA,i,timeA);
if (verbose == 1) { System.out.println("A* takes "+ Long.toString(100*(timeA+1)/(timeD+1)) +"% of Dijkstra's execution time");}
} }
juste += test(graph,"A*",drawing); if (verbose == 1) { System.out.println("Test number " + Integer.toString(i));}
justeD += test(graph,"D",drawing, id1, id2);
justeA += test(graph,"A*",drawing,id1, id2);
} }
System.out.println( if (verbose == 1) { System.out.println("===== Final Results =====");}
"number of good tests : " + Integer.toString(juste) + "/" + Integer.toString(nbTest*2) displayResult("Dijkstra",justeD,nbTest,timeD);
); displayResult("A*",justeA,nbTest,timeA);
if (verbose == 1) { System.out.println("A* takes "+ Long.toString(100*timeA/timeD) +"% of Dijkstra's execution time");}
} }
} }

Vedi file

@ -23,5 +23,22 @@
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="src" path="target/generated-sources/annotations">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="m2e-apt" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="m2e-apt" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/> <classpathentry kind="output" path="target/classes"/>
</classpath> </classpath>

Vedi file

@ -36,16 +36,19 @@ public class Path {
if (nodes.size() == 1) { if (nodes.size() == 1) {
return new Path(graph, nodes.get(0)); return new Path(graph, nodes.get(0));
} }
if (nodes.size() == 1) {
return new Path(graph);
}
List<Arc> arcs = new ArrayList<Arc>(); List<Arc> arcs = new ArrayList<Arc>();
for (int i = 0 ; i < nodes.size(); i++) {
// we iterate over the list of nodes
for (int i = 0 ; i < nodes.size(); i++) {
Node currNode = nodes.get(i); Node currNode = nodes.get(i);
if (i < nodes.size() -1) {
if (i < nodes.size() -1) { // if it's not the last
Node nextNode = nodes.get(i+1); Node nextNode = nodes.get(i+1);
if (currNode.hasSuccessors()) { if (currNode.hasSuccessors()) {
Arc better = null; Arc better = null;
// we compare all the edges to pick the best one
for (Arc j : currNode.getSuccessors()) { for (Arc j : currNode.getSuccessors()) {
if (j.getDestination() == nextNode) { if (j.getDestination() == nextNode) {
if (better == null || better.getMinimumTravelTime() > j.getMinimumTravelTime()) { if (better == null || better.getMinimumTravelTime() > j.getMinimumTravelTime()) {
@ -53,6 +56,8 @@ public class Path {
} }
} }
} }
// If it exists we add it else we throw an exception
if (better == null) { if (better == null) {
throw (new IllegalArgumentException()); throw (new IllegalArgumentException());
} else { } else {
@ -80,19 +85,23 @@ public class Path {
*/ */
public static Path createShortestPathFromNodes(Graph graph, List<Node> nodes) public static Path createShortestPathFromNodes(Graph graph, List<Node> nodes)
throws IllegalArgumentException { throws IllegalArgumentException {
//
if (nodes.size() == 1) { if (nodes.size() == 1) {
return new Path(graph, nodes.get(0)); return new Path(graph, nodes.get(0));
} }
if (nodes.size() == 1) {
return new Path(graph);
}
List<Arc> arcs = new ArrayList<Arc>(); List<Arc> arcs = new ArrayList<Arc>();
// we iterate over the list of nodes
for (int i = 0 ; i < nodes.size(); i++) { for (int i = 0 ; i < nodes.size(); i++) {
Node currNode = nodes.get(i); Node currNode = nodes.get(i);
if (i < nodes.size() -1) {
if (i < nodes.size() -1) { // if it's not the last
Node nextNode = nodes.get(i+1); Node nextNode = nodes.get(i+1);
if (currNode.hasSuccessors()) { if (currNode.hasSuccessors()) {
Arc better = null; Arc better = null;
// we compare all the edges to pick the best one
for (Arc j : currNode.getSuccessors()) { for (Arc j : currNode.getSuccessors()) {
if (j.getDestination() == nextNode) { if (j.getDestination() == nextNode) {
if (better == null || better.getLength() > j.getLength()) { if (better == null || better.getLength() > j.getLength()) {
@ -100,6 +109,8 @@ public class Path {
} }
} }
} }
// If it exists we add it else we throw an exception
if (better == null) { if (better == null) {
throw (new IllegalArgumentException()); throw (new IllegalArgumentException());
} else { } else {
@ -253,17 +264,14 @@ public class Path {
*/ */
public boolean isValid() { public boolean isValid() {
Arc old = null; Arc old = null;
// it is empty
if (this.isEmpty()) { if (this.isEmpty()) {
// it is empty so true
return true; return true;
} }
// Origin is ok
if ((this.origin != null) && (this.arcs.size() == 0)) { if ((this.origin != null) && (this.arcs.size() == 0)) {
// only origin is ok: single node (without arcs)
return true; return true;
} }
if (this.arcs.size() == 0) {
return false;
}
// destination of the first one is the origin of the second node // destination of the first one is the origin of the second node
if (this.arcs.get(0).getOrigin() == this.origin) { if (this.arcs.get(0).getOrigin() == this.origin) {
for (Arc a : this.arcs) { for (Arc a : this.arcs) {
@ -292,6 +300,7 @@ public class Path {
*/ */
public float getLength() { public float getLength() {
float acc = 0; float acc = 0;
// sum all of the lengths
for (Arc l : this.arcs) { for (Arc l : this.arcs) {
acc += l.getLength(); acc += l.getLength();
} }
@ -309,7 +318,7 @@ public class Path {
* *
*/ */
public double getTravelTime(double speed) { public double getTravelTime(double speed) {
double speed2 = speed * 1000/3600; double speed2 = speed * 1000/3600; // conversion from km/h to m/s
return (this.getLength()/speed2); return (this.getLength()/speed2);
} }
@ -322,6 +331,7 @@ public class Path {
*/ */
public double getMinimumTravelTime() { public double getMinimumTravelTime() {
float acc = 0; float acc = 0;
// sum all of the minimum travel times
for (Arc l : this.arcs) { for (Arc l : this.arcs) {
acc += l.getMinimumTravelTime(); acc += l.getMinimumTravelTime();
} }

BIN
img.png

File binario non mostrato.

Prima

Larghezza:  |  Altezza:  |  Dimensione: 130 KiB

BIN
img2.png

File binario non mostrato.

Prima

Larghezza:  |  Altezza:  |  Dimensione: 40 KiB

Vedi file

@ -4,9 +4,9 @@ On a une liste de liste et non une matrice. L'avantage est de prendre bien moins
## Diagram UML ## Diagram UML
Diagrame UML : <br> Diagrame UML : <br>
<img src="./img.png"> <img src="./UML1.png">
## deuxieme diagram UML ## deuxieme diagram UML
Diagrame UML : <br> Diagrame UML : <br>
<img src="./img2.png"> <img src="./UML2.png">