Compare commits
3 commits
f62e312156
...
6af2ae2ead
Author | SHA1 | Date | |
---|---|---|---|
6af2ae2ead | |||
f852e39994 | |||
8e7d933e7a |
5 changed files with 417 additions and 803 deletions
|
@ -12,8 +12,6 @@ import org.insa.graphs.model.Path;
|
||||||
|
|
||||||
public class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
public class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
||||||
|
|
||||||
private float pathCost;
|
|
||||||
|
|
||||||
public DijkstraAlgorithm(ShortestPathData data) {
|
public DijkstraAlgorithm(ShortestPathData data) {
|
||||||
super(data);
|
super(data);
|
||||||
}
|
}
|
||||||
|
@ -146,8 +144,4 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
||||||
}
|
}
|
||||||
return solution;
|
return solution;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getCostPath() {
|
|
||||||
return this.pathCost;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ import org.insa.graphs.model.Node;
|
||||||
|
|
||||||
public abstract class ShortestPathAlgorithm extends AbstractAlgorithm<ShortestPathObserver> {
|
public abstract class ShortestPathAlgorithm extends AbstractAlgorithm<ShortestPathObserver> {
|
||||||
|
|
||||||
|
protected float pathCost;
|
||||||
|
|
||||||
protected ShortestPathAlgorithm(ShortestPathData data) {
|
protected ShortestPathAlgorithm(ShortestPathData data) {
|
||||||
super(data);
|
super(data);
|
||||||
}
|
}
|
||||||
|
@ -66,4 +68,8 @@ public abstract class ShortestPathAlgorithm extends AbstractAlgorithm<ShortestPa
|
||||||
obs.notifyDestinationReached(node);
|
obs.notifyDestinationReached(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float getCostPath() {
|
||||||
|
return this.pathCost;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,416 +1,14 @@
|
||||||
package org.insa.graphs.algorithm.shortestpath;
|
package org.insa.graphs.algorithm.shortestpath;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
public class AStarAlgorithmTest extends ShortestPathAlgorithmTest {
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
public AStarAlgorithmTest() {
|
||||||
import java.io.DataInputStream;
|
super();
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import org.insa.graphs.algorithm.ArcInspector;
|
|
||||||
import org.insa.graphs.algorithm.ArcInspectorFactory;
|
|
||||||
import org.insa.graphs.model.Graph;
|
|
||||||
import org.insa.graphs.model.Node;
|
|
||||||
import org.insa.graphs.model.Path;
|
|
||||||
import org.insa.graphs.model.io.BinaryGraphReader;
|
|
||||||
import org.insa.graphs.model.io.GraphReader;
|
|
||||||
import org.insa.graphs.model.io.PathReader;
|
|
||||||
import org.junit.BeforeClass;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runners.Parameterized.Parameter;
|
|
||||||
|
|
||||||
public class AStarAlgorithmTest {
|
|
||||||
|
|
||||||
public static GraphReader reader;
|
|
||||||
public static ArrayList<Graph> graph = new ArrayList<Graph>();
|
|
||||||
public static PathReader pathReader;
|
|
||||||
public static ArrayList<Path> path = new ArrayList<Path>();
|
|
||||||
|
|
||||||
@Parameter
|
|
||||||
// Liste de cartes utilisées
|
|
||||||
static ArrayList<String> Maps = new ArrayList<String>(Arrays.asList("../Maps/carre.mapgr",
|
|
||||||
"../Maps/insa.mapgr",
|
|
||||||
"../Maps/toulouse.mapgr",
|
|
||||||
"../Maps/midi-pyrenees.mapgr"));
|
|
||||||
|
|
||||||
@BeforeClass
|
|
||||||
/*
|
|
||||||
* Ajoute toute les cartes dans l'attribut graph.
|
|
||||||
* Ensuite, on testera des chemins dont qui sont disponibles dans custom_path.
|
|
||||||
* Ces chemins ont été tracés avec l'algo BellmanFord et sont donc considérés corrects.
|
|
||||||
* On ne crée pas les chemins dans un attribut, on va les "recréer" virtuellement à
|
|
||||||
* partir de leur origine/destination et en appliquant BellmanFord.
|
|
||||||
* Cela permet une meilleure adaptabilité du code.
|
|
||||||
*/
|
|
||||||
public static void init() {
|
|
||||||
try {
|
|
||||||
// Create the map
|
|
||||||
for (int j = 0 ; j < Maps.size() ; j++) {
|
|
||||||
final String mapName = Maps.get(j);
|
|
||||||
// Create a graph reader
|
|
||||||
final GraphReader reader = new BinaryGraphReader(
|
|
||||||
new DataInputStream(new BufferedInputStream(new FileInputStream(mapName))));
|
|
||||||
// Read the graph. X
|
|
||||||
graph.add(reader.read());
|
|
||||||
// free resources
|
|
||||||
reader.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (FileNotFoundException e) {
|
|
||||||
System.err.println("File not found: " + e.getMessage());
|
|
||||||
fail("File not found: " + e.getMessage());
|
|
||||||
}
|
|
||||||
catch (IOException e ) {
|
|
||||||
System.err.println("Error reading file: " + e.getMessage());
|
|
||||||
fail("Error reading file: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
/* Stratégie:
|
protected ShortestPathAlgorithm initAlgo(ShortestPathData data) {
|
||||||
* Chemins courts testés par comparaison avec Bellman.
|
return new AStarAlgorithm(data);
|
||||||
* Chemin longs testés par comparaison avec chemins déjà construits. Bellman trop long.
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Test
|
|
||||||
/*
|
|
||||||
* Map: carre.mapgr
|
|
||||||
* Chemin: 19 --> 4
|
|
||||||
* Tous chemins permis
|
|
||||||
* Mode: LENGTH
|
|
||||||
* PATH UTILISE : ../Paths/custom_paths/short_path_carre.path
|
|
||||||
*/
|
|
||||||
public void chemin_court_CARRE_length() {
|
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0);
|
|
||||||
Graph myGraph = graph.get(0);
|
|
||||||
Node origin = myGraph.get(19);
|
|
||||||
Node destination = myGraph.get(4);
|
|
||||||
ShortestPathData data = new ShortestPathData(myGraph, origin, destination, arcInspector);
|
|
||||||
|
|
||||||
AStarAlgorithm astar = new AStarAlgorithm(data);
|
|
||||||
ShortestPathSolution astar_path = astar.doRun();
|
|
||||||
|
|
||||||
BellmanFordAlgorithm bellman = new BellmanFordAlgorithm(data);
|
|
||||||
ShortestPathSolution bell_path = bellman.doRun();
|
|
||||||
|
|
||||||
assert(astar_path.getPath().isValid());
|
|
||||||
assert(astar_path.isFeasible());
|
|
||||||
assert(Math.abs(astar.getCostPath() - astar_path.getPath().getLength()) < 1.0);
|
|
||||||
assert(Math.abs(astar_path.getPath().getLength() - bell_path.getPath().getLength()) < 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
/*
|
|
||||||
* Chemin long relativement à la carte carrée.
|
|
||||||
* Chemin: 15 --> 9
|
|
||||||
* Tous chemins permis
|
|
||||||
* PATH UTILISE : ../Paths/custom_paths/long_path_carre.path
|
|
||||||
*/
|
|
||||||
public void chemin_long_CARRE_length() {
|
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0);
|
|
||||||
Graph myGraph = graph.get(0);
|
|
||||||
Node origin = myGraph.get(15);
|
|
||||||
Node destination = myGraph.get(9);
|
|
||||||
|
|
||||||
ShortestPathData data = new ShortestPathData(myGraph, origin, destination, arcInspector);
|
|
||||||
|
|
||||||
AStarAlgorithm astar = new AStarAlgorithm(data);
|
|
||||||
ShortestPathSolution astar_path = astar.doRun();
|
|
||||||
|
|
||||||
BellmanFordAlgorithm bellman = new BellmanFordAlgorithm(data);
|
|
||||||
ShortestPathSolution bell_path = bellman.doRun();
|
|
||||||
|
|
||||||
assert(astar_path.getPath().isValid());
|
|
||||||
assert(astar_path.isFeasible());
|
|
||||||
assert(Math.abs(astar.getCostPath() - astar_path.getPath().getLength()) < 1.0);
|
|
||||||
assert(Math.abs(astar_path.getPath().getLength() - bell_path.getPath().getLength()) < 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
/*
|
|
||||||
* Chemin nul sur carte carrée.
|
|
||||||
* L'origine et la destination sont les mêmes (noeud 3).
|
|
||||||
* Tous chemins permis
|
|
||||||
*/
|
|
||||||
public void chemin_nul_CARRE() {
|
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0);
|
|
||||||
Graph myGraph = graph.get(0);
|
|
||||||
Node origin = myGraph.get(3);
|
|
||||||
Node destination = myGraph.get(3);
|
|
||||||
ShortestPathData data = new ShortestPathData(myGraph, origin, destination, arcInspector);
|
|
||||||
|
|
||||||
AStarAlgorithm astar = new AStarAlgorithm(data);
|
|
||||||
ShortestPathSolution astar_path = astar.doRun();
|
|
||||||
|
|
||||||
assert(!astar_path.isFeasible());
|
|
||||||
assert(astar_path.getPath() == null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
/*
|
|
||||||
* Chemin inexistant sur la carte INSA.
|
|
||||||
* Origine: 224
|
|
||||||
* Destination: 814.
|
|
||||||
* Les 2 noeuds font partie de deux composantes non connexes.
|
|
||||||
* Tous chemins permis.
|
|
||||||
*/
|
|
||||||
public void chemin_inexistant_INSA() {
|
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0);
|
|
||||||
Graph myGraph = graph.get(1);
|
|
||||||
Node origin = myGraph.get(224);
|
|
||||||
Node destination = myGraph.get(814);
|
|
||||||
ShortestPathData data = new ShortestPathData(myGraph, origin, destination, arcInspector);
|
|
||||||
|
|
||||||
AStarAlgorithm astar = new AStarAlgorithm(data);
|
|
||||||
ShortestPathSolution astar_path = astar.doRun();
|
|
||||||
assert(!astar_path.isFeasible());
|
|
||||||
assert(astar_path.getPath() == null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
/*
|
|
||||||
* Chemin court sur la carte de Toulouse.
|
|
||||||
* Origine : 8423
|
|
||||||
* Destination: 8435
|
|
||||||
* Tous chemins permis.
|
|
||||||
* PATH UTILISE : ../Paths/custom_paths/short_path_tls.path
|
|
||||||
*/
|
|
||||||
public void chemin_court_TLS() {
|
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0);
|
|
||||||
Graph myGraph = graph.get(2);
|
|
||||||
Node origin = myGraph.get(8423);
|
|
||||||
Node destination = myGraph.get(8435);
|
|
||||||
ShortestPathData data = new ShortestPathData(myGraph, origin, destination, arcInspector);
|
|
||||||
|
|
||||||
AStarAlgorithm astar = new AStarAlgorithm(data);
|
|
||||||
ShortestPathSolution astar_path = astar.doRun();
|
|
||||||
|
|
||||||
BellmanFordAlgorithm bellman = new BellmanFordAlgorithm(data);
|
|
||||||
ShortestPathSolution bell_path = bellman.doRun();
|
|
||||||
|
|
||||||
assert(astar_path.getPath().isValid());
|
|
||||||
assert(astar_path.isFeasible());
|
|
||||||
assert(Math.abs(astar.getCostPath() - astar_path.getPath().getLength()) < 1.0);
|
|
||||||
assert(Math.abs(astar_path.getPath().getLength() - bell_path.getPath().getLength()) < 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
/*
|
|
||||||
* Chemin long sur la carte de Toulouse.
|
|
||||||
* Même si Bellman est de plus long à faire long à faire, ce test prend moins
|
|
||||||
* de 3s, on estime que ce n'est pas trop et on va utiliser Bellman.
|
|
||||||
* Par contre, dans le test sur la région midi_pyrenees qui arrive après, on va
|
|
||||||
* être obligé de trouver une autre solution.
|
|
||||||
* Origine: 16644
|
|
||||||
* Destination: 39229
|
|
||||||
* Mode: LENGTH
|
|
||||||
* PATH UTILISE : ../Paths/custom_paths/long_path_tls.path
|
|
||||||
*/
|
|
||||||
public void chemin_long_TLS_length() {
|
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0);
|
|
||||||
Graph myGraph = graph.get(2);
|
|
||||||
Node origin = myGraph.get(16644);
|
|
||||||
Node destination = myGraph.get(39229);
|
|
||||||
ShortestPathData data = new ShortestPathData(myGraph, origin, destination, arcInspector);
|
|
||||||
|
|
||||||
AStarAlgorithm astar = new AStarAlgorithm(data);
|
|
||||||
ShortestPathSolution astar_path = astar.doRun();
|
|
||||||
|
|
||||||
BellmanFordAlgorithm bellman = new BellmanFordAlgorithm(data);
|
|
||||||
ShortestPathSolution bell_path = bellman.doRun();
|
|
||||||
|
|
||||||
assert(astar_path.getPath().isValid());
|
|
||||||
assert(astar_path.isFeasible());
|
|
||||||
assert((Math.abs(astar.getCostPath() - astar_path.getPath().getLength()) < 1.0));
|
|
||||||
assert(Math.abs(astar_path.getPath().getLength() - bell_path.getPath().getLength()) < 10.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
/*
|
|
||||||
* Chemin long sur la carte de Toulouse.
|
|
||||||
* Comme à cette étape Dijkstra a été testé, on va l'utiliser pour vérifier
|
|
||||||
* AStar. On considère que Dijkstra est correct et vérifié.
|
|
||||||
* Origine: 16644
|
|
||||||
* Destination: 39229
|
|
||||||
* Mode: TIME
|
|
||||||
* PATH UTILISE : ../Paths/custom_paths/long_path_tls.path
|
|
||||||
*/
|
|
||||||
public void chemin_long_TLS_time() {
|
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(2);
|
|
||||||
Graph myGraph = graph.get(2);
|
|
||||||
Node origin = myGraph.get(16644);
|
|
||||||
Node destination = myGraph.get(39229);
|
|
||||||
ShortestPathData data = new ShortestPathData(myGraph, origin, destination, arcInspector);
|
|
||||||
|
|
||||||
AStarAlgorithm astar = new AStarAlgorithm(data);
|
|
||||||
ShortestPathSolution astar_path = astar.doRun();
|
|
||||||
|
|
||||||
DijkstraAlgorithm dijkstra = new DijkstraAlgorithm(data);
|
|
||||||
ShortestPathSolution dijkstra_path = dijkstra.doRun();
|
|
||||||
|
|
||||||
assert(astar_path.getPath().isValid());
|
|
||||||
assert(astar_path.isFeasible());
|
|
||||||
assert((Math.abs(astar.getCostPath() - astar_path.getPath().getMinimumTravelTime()) < 1.0));
|
|
||||||
assert(Math.abs(astar.getCostPath() - dijkstra.getCostPath()) < 1.0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
/*
|
|
||||||
* Test du mode à vélo facultatif.
|
|
||||||
* Nous prenons une origine sur l'autoroute et une destination en dehors.
|
|
||||||
* Ce chemin est donc censé être utilisable en vélo mais pas en voiture.
|
|
||||||
* Avec le filtre vélos, on obtient pas de chemin.
|
|
||||||
* Avec le filtre voitures on obtient un chemin.
|
|
||||||
* Origine: 19135
|
|
||||||
* Destination: 1980
|
|
||||||
* PATH UTILISE : ../Paths/custom_paths/path_cyclist.path
|
|
||||||
*/
|
|
||||||
public void chemin_velo_uniquement() {
|
|
||||||
// Filter: forBicyclesCustomT
|
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(4);
|
|
||||||
|
|
||||||
Graph myGraph = graph.get(2);
|
|
||||||
Node origin = myGraph.get(19135);
|
|
||||||
Node destination = myGraph.get(1980);
|
|
||||||
|
|
||||||
ShortestPathData data = new ShortestPathData(myGraph, origin, destination, arcInspector);
|
|
||||||
|
|
||||||
AStarAlgorithm astar_bicycle = new AStarAlgorithm(data);
|
|
||||||
ShortestPathSolution astar_path_bicycle = astar_bicycle.doRun();
|
|
||||||
|
|
||||||
BellmanFordAlgorithm bellman_bicycle = new BellmanFordAlgorithm(data);
|
|
||||||
ShortestPathSolution bell_path_bicycle = bellman_bicycle.doRun();
|
|
||||||
|
|
||||||
// Filter: forCarsL
|
|
||||||
ArcInspector new_Inspector = ArcInspectorFactory.getAllFilters().get(1);
|
|
||||||
data = new ShortestPathData(myGraph, origin, destination, new_Inspector);
|
|
||||||
|
|
||||||
AStarAlgorithm astar_car = new AStarAlgorithm(data);
|
|
||||||
ShortestPathSolution astar_path_car = astar_car.doRun();
|
|
||||||
|
|
||||||
assertEquals(astar_path_bicycle.getPath(), null);
|
|
||||||
assert(!astar_path_bicycle.isFeasible());
|
|
||||||
assertEquals(bell_path_bicycle.getPath(), null);
|
|
||||||
assert(!bell_path_bicycle.isFeasible());
|
|
||||||
|
|
||||||
assert(astar_path_car.getPath() != null);
|
|
||||||
assert(astar_path_car.isFeasible());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
/*
|
|
||||||
* On veut vérifier le bon fonctionnement des modes TIME et LENGTH.
|
|
||||||
* Pour cela, on va obtenir deux chemins avec l'algo de astar et vérifier
|
|
||||||
* que:
|
|
||||||
* -le chemin TIME est plus rapide en durée que le chemin LENGTH
|
|
||||||
* -le chemin LENGTH est plus court en distance que le chemin LENGTH.
|
|
||||||
* On prend un grand chemin pour être sur d'avoir une différence :
|
|
||||||
* Origine: 16644
|
|
||||||
* Destination: 39229
|
|
||||||
* Mode: TIME/LENGTH
|
|
||||||
* PATH UTILISE : ../Paths/custom_paths/long_path_tls.path
|
|
||||||
*/
|
|
||||||
public void chemin_time_length_comparison() {
|
|
||||||
Graph myGraph = graph.get(2);
|
|
||||||
Node origin = myGraph.get(19135);
|
|
||||||
Node destination = myGraph.get(1980);
|
|
||||||
|
|
||||||
// Filter: forCarsL
|
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(1);
|
|
||||||
ShortestPathData data = new ShortestPathData(myGraph, origin, destination, arcInspector);
|
|
||||||
|
|
||||||
AStarAlgorithm astar_L = new AStarAlgorithm(data);
|
|
||||||
ShortestPathSolution astar_path_L = astar_L.doRun();
|
|
||||||
|
|
||||||
// Filter: forCarsT
|
|
||||||
ArcInspector new_Inspector = ArcInspectorFactory.getAllFilters().get(2);
|
|
||||||
data = new ShortestPathData(myGraph, origin, destination, new_Inspector);
|
|
||||||
|
|
||||||
AStarAlgorithm astar_T = new AStarAlgorithm(data);
|
|
||||||
ShortestPathSolution astar_path_T = astar_T.doRun();
|
|
||||||
|
|
||||||
assert(astar_path_L.getPath().isValid());
|
|
||||||
assert(astar_path_L.isFeasible());
|
|
||||||
assert(astar_path_T.getPath().isValid());
|
|
||||||
assert(astar_path_T.isFeasible());
|
|
||||||
|
|
||||||
assert((Math.abs(astar_L.getCostPath() - astar_path_L.getPath().getLength()) < 1.0));
|
|
||||||
assert((Math.abs(astar_T.getCostPath() - astar_path_T.getPath().getMinimumTravelTime()) < 1.0));
|
|
||||||
|
|
||||||
assert(astar_path_L.getPath().getLength() < astar_path_T.getPath().getLength());
|
|
||||||
assert(astar_path_L.getPath().getMinimumTravelTime() > astar_path_T.getPath().getMinimumTravelTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
/*
|
|
||||||
* Cette fois-ci, Bellman est trop long à utiliser même une seule fois.
|
|
||||||
* On va donc utiliser quelques techniques pour se rassurer.
|
|
||||||
* -vérifier certains noeuds comme départ, destination, noeud pivot.
|
|
||||||
* -vérifier le cout avec une estimation gentille.
|
|
||||||
* -etc.
|
|
||||||
* Origin: 279654
|
|
||||||
* Destination: 481936
|
|
||||||
* Mode: LENGTH
|
|
||||||
* PATH UTILISE : ../Paths/custom_paths/long_chemin_midi_pyrenees.path
|
|
||||||
*/
|
|
||||||
public void chemin_long_Midi_pyrenees_length() {
|
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0);
|
|
||||||
Graph myGraph = graph.get(3);
|
|
||||||
Node origin = myGraph.get(279654);
|
|
||||||
Node destination = myGraph.get(481936);
|
|
||||||
ShortestPathData data = new ShortestPathData(myGraph, origin, destination, arcInspector);
|
|
||||||
|
|
||||||
AStarAlgorithm astar = new AStarAlgorithm(data);
|
|
||||||
ShortestPathSolution astar_path = astar.doRun();
|
|
||||||
|
|
||||||
assert(astar_path.getPath().isValid());
|
|
||||||
assert(astar_path.isFeasible());
|
|
||||||
// On a des erreurs d'arrondi assez grande avec la distance, mais elles sont mineures
|
|
||||||
// relativement aux distance de 300000 ici.
|
|
||||||
assert((Math.abs(astar.getCostPath() - astar_path.getPath().getLength())) < 1000.0);
|
|
||||||
// Selon le chemin sélectionné on peut avoir une estimation de la longueur qu'on est censée avoir.
|
|
||||||
// Avec notre long chemin: entre 250 et 260 kilomètres.
|
|
||||||
assert(astar.getCostPath() > 250000 && astar.getCostPath() < 260000);
|
|
||||||
// On peut aussi supposer que le nombre d'arcs empruntés est très grand.
|
|
||||||
assert(astar_path.getPath().getArcs().size() > 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
/*
|
|
||||||
* Cette fois-ci, Bellman est trop long à utiliser même une seule fois.
|
|
||||||
* On va donc utiliser quelques techniques pour se rassurer.
|
|
||||||
* -vérifier certains noeuds comme départ, destination, noeud pivot.
|
|
||||||
* -vérifier le cout avec une estimation gentille.
|
|
||||||
* -etc.
|
|
||||||
* Origin: 279654
|
|
||||||
* Destination: 481936
|
|
||||||
* Mode: LENGTH
|
|
||||||
* PATH UTILISE : ../Paths/custom_paths/long_chemin_midi_pyrenees.path
|
|
||||||
*/
|
|
||||||
public void chemin_long_Midi_pyrenees_time() {
|
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(2);
|
|
||||||
Graph myGraph = graph.get(3);
|
|
||||||
Node origin = myGraph.get(279654);
|
|
||||||
Node destination = myGraph.get(481936);
|
|
||||||
ShortestPathData data = new ShortestPathData(myGraph, origin, destination, arcInspector);
|
|
||||||
|
|
||||||
AStarAlgorithm astar = new AStarAlgorithm(data);
|
|
||||||
ShortestPathSolution astar_path = astar.doRun();
|
|
||||||
|
|
||||||
assert(astar_path.getPath().isValid());
|
|
||||||
assert(astar_path.isFeasible());
|
|
||||||
// On a des erreurs d'arrondi assez grandes avec la distance
|
|
||||||
assert((Math.abs(astar.getCostPath() - astar_path.getPath().getMinimumTravelTime())) < 100.0);
|
|
||||||
// Selon le chemin sélectionné on peut avoir une estimation de la durée qu'on est censée avoir.
|
|
||||||
// Avec notre long chemin: entre 12000 et 13000 secondes.
|
|
||||||
assert(astar.getCostPath() > 12000 && astar.getCostPath() < 13000);
|
|
||||||
// On peut aussi supposer que le nombre d'arcs empruntés est très grand.
|
|
||||||
assert(astar_path.getPath().getArcs().size() > 1000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,397 +1,14 @@
|
||||||
package org.insa.graphs.algorithm.shortestpath;
|
package org.insa.graphs.algorithm.shortestpath;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
public class DijkstraAlgorithmTest extends ShortestPathAlgorithmTest {
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
public DijkstraAlgorithmTest() {
|
||||||
import java.io.DataInputStream;
|
super();
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import org.insa.graphs.algorithm.ArcInspector;
|
|
||||||
import org.insa.graphs.algorithm.ArcInspectorFactory;
|
|
||||||
import org.insa.graphs.model.Graph;
|
|
||||||
import org.insa.graphs.model.Node;
|
|
||||||
import org.insa.graphs.model.Path;
|
|
||||||
import org.insa.graphs.model.io.BinaryGraphReader;
|
|
||||||
import org.insa.graphs.model.io.GraphReader;
|
|
||||||
import org.insa.graphs.model.io.PathReader;
|
|
||||||
import org.junit.BeforeClass;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runners.Parameterized.Parameter;
|
|
||||||
|
|
||||||
public class DijkstraAlgorithmTest {
|
|
||||||
|
|
||||||
public static GraphReader reader;
|
|
||||||
public static ArrayList<Graph> graph = new ArrayList<Graph>();
|
|
||||||
public static PathReader pathReader;
|
|
||||||
public static ArrayList<Path> path = new ArrayList<Path>();
|
|
||||||
|
|
||||||
@Parameter
|
|
||||||
// Liste de cartes utilisées
|
|
||||||
static ArrayList<String> Maps = new ArrayList<String>(Arrays.asList("../Maps/carre.mapgr",
|
|
||||||
"../Maps/insa.mapgr",
|
|
||||||
"../Maps/toulouse.mapgr",
|
|
||||||
"../Maps/midi-pyrenees.mapgr"));
|
|
||||||
|
|
||||||
@BeforeClass
|
|
||||||
/*
|
|
||||||
* Ajoute toute les cartes dans l'attribut graph.
|
|
||||||
* Ensuite, on testera des chemins dont qui sont disponibles dans custom_path.
|
|
||||||
* Ces chemins ont été tracés avec l'algo BellmanFord et sont donc considérés corrects.
|
|
||||||
* On ne crée pas les chemins dans un attribut, on va les "recréer" virtuellement à
|
|
||||||
* partir de leur origine/destination et en appliquant BellmanFord.
|
|
||||||
* Cela permet une meilleure adaptabilité du code.
|
|
||||||
*/
|
|
||||||
public static void init() {
|
|
||||||
try {
|
|
||||||
// Create the map
|
|
||||||
for (String mapName : Maps) {
|
|
||||||
// Create a graph reader
|
|
||||||
final GraphReader reader = new BinaryGraphReader(
|
|
||||||
new DataInputStream(new BufferedInputStream(new FileInputStream(mapName))));
|
|
||||||
// Read the graph.
|
|
||||||
graph.add(reader.read());
|
|
||||||
// free resources
|
|
||||||
reader.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (FileNotFoundException e) {
|
|
||||||
System.err.println("File not found: " + e.getMessage());
|
|
||||||
fail("File not found: " + e.getMessage());
|
|
||||||
}
|
|
||||||
catch (IOException e ) {
|
|
||||||
System.err.println("Error reading file: " + e.getMessage());
|
|
||||||
fail("Error reading file: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
/* Stratégie:
|
protected ShortestPathAlgorithm initAlgo(ShortestPathData data) {
|
||||||
* Chemins courts testés par comparaison avec Bellman.
|
return new DijkstraAlgorithm(data);
|
||||||
* Chemin longs testés par comparaison avec chemins déjà construits. Bellman trop long.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Verifies that path is valid and mathes the one found by the Bellman algo
|
|
||||||
*/
|
|
||||||
private void assertBellmanHasSameResult(Graph graph, Node origin, Node destination, ArcInspector arcFilter) {
|
|
||||||
final ShortestPathData data = new ShortestPathData(graph, origin, destination, arcFilter);
|
|
||||||
|
|
||||||
final DijkstraAlgorithm dijkstra = new DijkstraAlgorithm(data);
|
|
||||||
final ShortestPathSolution dijk_path = dijkstra.doRun();
|
|
||||||
|
|
||||||
final BellmanFordAlgorithm bellman = new BellmanFordAlgorithm(data);
|
|
||||||
final ShortestPathSolution bell_path = bellman.doRun();
|
|
||||||
|
|
||||||
assert(dijk_path.getPath().isValid());
|
|
||||||
assert(dijk_path.isFeasible());
|
|
||||||
assert(Math.abs(dijkstra.getCostPath() - dijk_path.getPath().getLength()) < 1.0);
|
|
||||||
assert(Math.abs(dijk_path.getPath().getLength() - bell_path.getPath().getLength()) < 1.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Verifies that no path is found
|
|
||||||
*/
|
|
||||||
private void assertNoPathFound(Graph graph, Node origin, Node destination, ArcInspector arcFilter) {
|
|
||||||
ShortestPathData data = new ShortestPathData(graph, origin, destination, arcFilter);
|
|
||||||
|
|
||||||
DijkstraAlgorithm dijkstra = new DijkstraAlgorithm(data);
|
|
||||||
ShortestPathSolution dijk_path = dijkstra.doRun();
|
|
||||||
|
|
||||||
assert(!dijk_path.isFeasible());
|
|
||||||
assert(dijk_path.getPath() == null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
/*
|
|
||||||
* Map: carre.mapgr
|
|
||||||
* Chemin: 19 --> 4
|
|
||||||
* Tous chemins permis
|
|
||||||
* Mode: LENGTH
|
|
||||||
* PATH UTILISE : ../Paths/custom_paths/short_path_carre.path
|
|
||||||
*/
|
|
||||||
public void chemin_court_CARRE_length() {
|
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0); // all arcs
|
|
||||||
Graph myGraph = graph.get(0);
|
|
||||||
Node origin = myGraph.get(19);
|
|
||||||
Node destination = myGraph.get(4);
|
|
||||||
|
|
||||||
assertBellmanHasSameResult(myGraph, origin, destination, arcInspector);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
/*
|
|
||||||
* Chemin long relativement à la carte carrée.
|
|
||||||
* Chemin: 15 --> 9
|
|
||||||
* Tous chemins permis
|
|
||||||
* PATH UTILISE : ../Paths/custom_paths/long_path_carre.path
|
|
||||||
*/
|
|
||||||
public void chemin_long_CARRE_length() {
|
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0);
|
|
||||||
Graph myGraph = graph.get(0);
|
|
||||||
Node origin = myGraph.get(15);
|
|
||||||
Node destination = myGraph.get(9);
|
|
||||||
|
|
||||||
assertBellmanHasSameResult(myGraph, origin, destination, arcInspector);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
/*
|
|
||||||
* Chemin nul sur carte carrée.
|
|
||||||
* L'origine et la destination sont les mêmes (noeud 3).
|
|
||||||
* Tous chemins permis
|
|
||||||
*/
|
|
||||||
public void chemin_nul_CARRE() {
|
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0);
|
|
||||||
Graph myGraph = graph.get(0);
|
|
||||||
Node origin = myGraph.get(3);
|
|
||||||
Node destination = myGraph.get(3);
|
|
||||||
|
|
||||||
assertNoPathFound(myGraph, origin, destination, arcInspector);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
/*
|
|
||||||
* Chemin inexistant sur la carte INSA.
|
|
||||||
* Origine: 224
|
|
||||||
* Destination: 814.
|
|
||||||
* Les 2 noeuds font partie de deux composantes non connexes.
|
|
||||||
* Tous chemins permis.
|
|
||||||
*/
|
|
||||||
public void chemin_inexistant_INSA() {
|
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0);
|
|
||||||
Graph myGraph = graph.get(1);
|
|
||||||
Node origin = myGraph.get(224);
|
|
||||||
Node destination = myGraph.get(814);
|
|
||||||
|
|
||||||
assertNoPathFound(myGraph, origin, destination, arcInspector);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
/*
|
|
||||||
* Chemin court sur la carte de Toulouse.
|
|
||||||
* Origine : 8423
|
|
||||||
* Destination: 8435
|
|
||||||
* Tous chemins permis.
|
|
||||||
* PATH UTILISE : ../Paths/custom_paths/short_path_tls.path
|
|
||||||
*/
|
|
||||||
public void chemin_court_TLS() {
|
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0);
|
|
||||||
Graph myGraph = graph.get(2);
|
|
||||||
Node origin = myGraph.get(8423);
|
|
||||||
Node destination = myGraph.get(8435);
|
|
||||||
|
|
||||||
assertBellmanHasSameResult(myGraph, origin, destination, arcInspector);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
/*
|
|
||||||
* Chemin long sur la carte de Toulouse.
|
|
||||||
* Même si Bellman est de plus long à faire long à faire, ce test prend moins
|
|
||||||
* de 3s, on estime que ce n'est pas trop et on va utiliser Bellman.
|
|
||||||
* Par contre, dans le test sur la région midi_pyrenees qui arrive après, on va
|
|
||||||
* être obligé de trouver une autre solution.
|
|
||||||
* Origine: 16644
|
|
||||||
* Destination: 39229
|
|
||||||
* Mode: LENGTH
|
|
||||||
* PATH UTILISE : ../Paths/custom_paths/long_path_tls.path
|
|
||||||
*/
|
|
||||||
public void chemin_long_TLS_length() {
|
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0);
|
|
||||||
Graph myGraph = graph.get(2);
|
|
||||||
Node origin = myGraph.get(16644);
|
|
||||||
Node destination = myGraph.get(39229);
|
|
||||||
|
|
||||||
assertBellmanHasSameResult(myGraph, origin, destination, arcInspector);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
/*
|
|
||||||
* Chemin long sur la carte de Toulouse.
|
|
||||||
* Même si Bellman est de plus long à faire long à faire, ce test prend moins
|
|
||||||
* de 3s, on estime que ce n'est pas trop et on va utiliser Bellman.
|
|
||||||
* Par contre, dans le test sur la région midi_pyrenees qui arrive après, on va
|
|
||||||
* être obligé de trouver une autre solution.
|
|
||||||
* Origine: 16644
|
|
||||||
* Destination: 39229
|
|
||||||
* Mode: TIME
|
|
||||||
* PATH UTILISE : ../Paths/custom_paths/long_path_tls.path
|
|
||||||
*/
|
|
||||||
public void chemin_long_TLS_time() {
|
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(2);
|
|
||||||
Graph myGraph = graph.get(2);
|
|
||||||
Node origin = myGraph.get(16644);
|
|
||||||
Node destination = myGraph.get(39229);
|
|
||||||
ShortestPathData data = new ShortestPathData(myGraph, origin, destination, arcInspector);
|
|
||||||
|
|
||||||
DijkstraAlgorithm dijkstra = new DijkstraAlgorithm(data);
|
|
||||||
ShortestPathSolution dijk_path = dijkstra.doRun();
|
|
||||||
|
|
||||||
BellmanFordAlgorithm bellman = new BellmanFordAlgorithm(data);
|
|
||||||
ShortestPathSolution bell_path = bellman.doRun();
|
|
||||||
|
|
||||||
assert(dijk_path.getPath().isValid());
|
|
||||||
assert(dijk_path.isFeasible());
|
|
||||||
assert((Math.abs(dijkstra.getCostPath() - dijk_path.getPath().getMinimumTravelTime()) < 1.0));
|
|
||||||
assert(Math.abs(dijk_path.getPath().getMinimumTravelTime() - bell_path.getPath().getMinimumTravelTime()) < 10.0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
/*
|
|
||||||
* Test du mode à vélo facultatif.
|
|
||||||
* Nous prenons une origine sur l'autoroute et une destination en dehors.
|
|
||||||
* Ce chemin est donc censé être utilisable en vélo mais pas en voiture.
|
|
||||||
* Avec le filtre vélos, on obtient pas de chemin.
|
|
||||||
* Avec le filtre voitures on obtient un chemin.
|
|
||||||
* Origine: 19135
|
|
||||||
* Destination: 1980
|
|
||||||
* PATH UTILISE : ../Paths/custom_paths/path_cyclist.path
|
|
||||||
*/
|
|
||||||
public void chemin_velo_uniquement() {
|
|
||||||
// Filter: forBicyclesCustomT
|
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(4);
|
|
||||||
|
|
||||||
Graph myGraph = graph.get(2);
|
|
||||||
Node origin = myGraph.get(19135);
|
|
||||||
Node destination = myGraph.get(1980);
|
|
||||||
|
|
||||||
ShortestPathData data = new ShortestPathData(myGraph, origin, destination, arcInspector);
|
|
||||||
|
|
||||||
DijkstraAlgorithm dijkstra_bicycle = new DijkstraAlgorithm(data);
|
|
||||||
ShortestPathSolution dijk_path_bicycle = dijkstra_bicycle.doRun();
|
|
||||||
|
|
||||||
BellmanFordAlgorithm bellman_bicycle = new BellmanFordAlgorithm(data);
|
|
||||||
ShortestPathSolution bell_path_bicycle = bellman_bicycle.doRun();
|
|
||||||
|
|
||||||
// Filter: forCarsL
|
|
||||||
ArcInspector new_Inspector = ArcInspectorFactory.getAllFilters().get(1);
|
|
||||||
data = new ShortestPathData(myGraph, origin, destination, new_Inspector);
|
|
||||||
|
|
||||||
DijkstraAlgorithm dijkstra_car = new DijkstraAlgorithm(data);
|
|
||||||
ShortestPathSolution dijk_path_car = dijkstra_car.doRun();
|
|
||||||
|
|
||||||
assertEquals(dijk_path_bicycle.getPath(), null);
|
|
||||||
assert(!dijk_path_bicycle.isFeasible());
|
|
||||||
assertEquals(bell_path_bicycle.getPath(), null);
|
|
||||||
assert(!bell_path_bicycle.isFeasible());
|
|
||||||
|
|
||||||
assert(dijk_path_car.getPath() != null);
|
|
||||||
assert(dijk_path_car.isFeasible());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
/*
|
|
||||||
* On veut vérifier le bon fonctionnement des modes TIME et LENGTH.
|
|
||||||
* Pour cela, on va obtenir deux chemins avec l'algo de Dijkstra et vérifier
|
|
||||||
* que:
|
|
||||||
* -le chemin TIME est plus rapide en durée que le chemin LENGTH
|
|
||||||
* -le chemin LENGTH est plus court en distance que le chemin LENGTH.
|
|
||||||
* On prend un grand chemin pour être sur d'avoir une différence :
|
|
||||||
* Origine: 16644
|
|
||||||
* Destination: 39229
|
|
||||||
* Mode: TIME/LENGTH
|
|
||||||
* PATH UTILISE : ../Paths/custom_paths/long_path_tls.path
|
|
||||||
*/
|
|
||||||
public void chemin_time_length_comparison() {
|
|
||||||
Graph myGraph = graph.get(2);
|
|
||||||
Node origin = myGraph.get(19135);
|
|
||||||
Node destination = myGraph.get(1980);
|
|
||||||
|
|
||||||
// Filter: forCarsL
|
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(1);
|
|
||||||
ShortestPathData data = new ShortestPathData(myGraph, origin, destination, arcInspector);
|
|
||||||
|
|
||||||
DijkstraAlgorithm dijkstra_L = new DijkstraAlgorithm(data);
|
|
||||||
ShortestPathSolution dijk_path_L = dijkstra_L.doRun();
|
|
||||||
|
|
||||||
// Filter: forCarsT
|
|
||||||
ArcInspector new_Inspector = ArcInspectorFactory.getAllFilters().get(2);
|
|
||||||
data = new ShortestPathData(myGraph, origin, destination, new_Inspector);
|
|
||||||
|
|
||||||
DijkstraAlgorithm dijkstra_T = new DijkstraAlgorithm(data);
|
|
||||||
ShortestPathSolution dijk_path_T = dijkstra_T.doRun();
|
|
||||||
|
|
||||||
assert(dijk_path_L.getPath().isValid());
|
|
||||||
assert(dijk_path_L.isFeasible());
|
|
||||||
assert(dijk_path_T.getPath().isValid());
|
|
||||||
assert(dijk_path_T.isFeasible());
|
|
||||||
|
|
||||||
assert((Math.abs(dijkstra_L.getCostPath() - dijk_path_L.getPath().getLength()) < 1.0));
|
|
||||||
assert((Math.abs(dijkstra_T.getCostPath() - dijk_path_T.getPath().getMinimumTravelTime()) < 1.0));
|
|
||||||
|
|
||||||
assert(dijk_path_L.getPath().getLength() < dijk_path_T.getPath().getLength());
|
|
||||||
assert(dijk_path_L.getPath().getMinimumTravelTime() > dijk_path_T.getPath().getMinimumTravelTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
/*
|
|
||||||
* Cette fois-ci, Bellman est trop long à utiliser même une seule fois.
|
|
||||||
* On va donc utiliser quelques techniques pour se rassurer.
|
|
||||||
* -vérifier certains noeuds comme départ, destination, noeud pivot.
|
|
||||||
* -vérifier le cout avec une estimation gentille.
|
|
||||||
* -etc.
|
|
||||||
* Origin: 279654
|
|
||||||
* Destination: 481936
|
|
||||||
* Mode: LENGTH
|
|
||||||
* PATH UTILISE : ../Paths/custom_paths/long_chemin_midi_pyrenees.path
|
|
||||||
*/
|
|
||||||
public void chemin_long_Midi_pyrenees_length() {
|
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0);
|
|
||||||
Graph myGraph = graph.get(3);
|
|
||||||
Node origin = myGraph.get(279654);
|
|
||||||
Node destination = myGraph.get(481936);
|
|
||||||
ShortestPathData data = new ShortestPathData(myGraph, origin, destination, arcInspector);
|
|
||||||
|
|
||||||
DijkstraAlgorithm dijkstra = new DijkstraAlgorithm(data);
|
|
||||||
ShortestPathSolution dijk_path = dijkstra.doRun();
|
|
||||||
|
|
||||||
assert(dijk_path.getPath().isValid());
|
|
||||||
assert(dijk_path.isFeasible());
|
|
||||||
// On a des erreurs d'arrondi assez grande avec la distance, mais elles sont mineures
|
|
||||||
// relativement aux distance de 300000 ici.
|
|
||||||
assert((Math.abs(dijkstra.getCostPath() - dijk_path.getPath().getLength())) < 1000.0);
|
|
||||||
// Selon le chemin sélectionné on peut avoir une estimation de la longueur qu'on est censée avoir.
|
|
||||||
// Avec notre long chemin: entre 250 et 260 kilomètres.
|
|
||||||
assert(dijkstra.getCostPath() > 250000 && dijkstra.getCostPath() < 260000);
|
|
||||||
// On peut aussi supposer que le nombre d'arcs empruntés est très grand.
|
|
||||||
assert(dijk_path.getPath().getArcs().size() > 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
/*
|
|
||||||
* Cette fois-ci, Bellman est trop long à utiliser même une seule fois.
|
|
||||||
* On va donc utiliser quelques techniques pour se rassurer.
|
|
||||||
* -vérifier certains noeuds comme départ, destination, noeud pivot.
|
|
||||||
* -vérifier le cout avec une estimation gentille.
|
|
||||||
* -etc.
|
|
||||||
* Origin: 279654
|
|
||||||
* Destination: 481936
|
|
||||||
* Mode: LENGTH
|
|
||||||
* PATH UTILISE : ../Paths/custom_paths/long_chemin_midi_pyrenees.path
|
|
||||||
*/
|
|
||||||
public void chemin_long_Midi_pyrenees_time() {
|
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(2);
|
|
||||||
Graph myGraph = graph.get(3);
|
|
||||||
Node origin = myGraph.get(279654);
|
|
||||||
Node destination = myGraph.get(481936);
|
|
||||||
ShortestPathData data = new ShortestPathData(myGraph, origin, destination, arcInspector);
|
|
||||||
|
|
||||||
DijkstraAlgorithm dijkstra = new DijkstraAlgorithm(data);
|
|
||||||
ShortestPathSolution dijk_path = dijkstra.doRun();
|
|
||||||
|
|
||||||
assert(dijk_path.getPath().isValid());
|
|
||||||
assert(dijk_path.isFeasible());
|
|
||||||
// On a des erreurs d'arrondi assez grandes avec la distance
|
|
||||||
assert((Math.abs(dijkstra.getCostPath() - dijk_path.getPath().getMinimumTravelTime())) < 100.0);
|
|
||||||
// Selon le chemin sélectionné on peut avoir une estimation de la durée qu'on est censée avoir.
|
|
||||||
// Avec notre long chemin: entre 12000 et 13000 secondes.
|
|
||||||
assert(dijkstra.getCostPath() > 12000 && dijkstra.getCostPath() < 13000);
|
|
||||||
// On peut aussi supposer que le nombre d'arcs empruntés est très grand.
|
|
||||||
assert(dijk_path.getPath().getArcs().size() > 1000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,399 @@
|
||||||
|
package org.insa.graphs.algorithm.shortestpath;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.insa.graphs.algorithm.ArcInspector;
|
||||||
|
import org.insa.graphs.algorithm.ArcInspectorFactory;
|
||||||
|
import org.insa.graphs.model.Graph;
|
||||||
|
import org.insa.graphs.model.Node;
|
||||||
|
import org.insa.graphs.model.Path;
|
||||||
|
import org.insa.graphs.model.io.BinaryGraphReader;
|
||||||
|
import org.insa.graphs.model.io.GraphReader;
|
||||||
|
import org.insa.graphs.model.io.PathReader;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runners.Parameterized.Parameter;
|
||||||
|
|
||||||
|
public abstract class ShortestPathAlgorithmTest {
|
||||||
|
|
||||||
|
public static GraphReader reader;
|
||||||
|
public static ArrayList<Graph> graph = new ArrayList<Graph>();
|
||||||
|
public static PathReader pathReader;
|
||||||
|
public static ArrayList<Path> path = new ArrayList<Path>();
|
||||||
|
|
||||||
|
protected abstract ShortestPathAlgorithm initAlgo(ShortestPathData data);
|
||||||
|
|
||||||
|
@Parameter
|
||||||
|
// Liste de cartes utilisées
|
||||||
|
static ArrayList<String> Maps = new ArrayList<String>(Arrays.asList("../Maps/carre.mapgr",
|
||||||
|
"../Maps/insa.mapgr",
|
||||||
|
"../Maps/toulouse.mapgr",
|
||||||
|
"../Maps/midi-pyrenees.mapgr"));
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
/*
|
||||||
|
* Ajoute toute les cartes dans l'attribut graph.
|
||||||
|
* Ensuite, on testera des chemins dont qui sont disponibles dans custom_path.
|
||||||
|
* Ces chemins ont été tracés avec l'algo BellmanFord et sont donc considérés corrects.
|
||||||
|
* On ne crée pas les chemins dans un attribut, on va les "recréer" virtuellement à
|
||||||
|
* partir de leur origine/destination et en appliquant BellmanFord.
|
||||||
|
* Cela permet une meilleure adaptabilité du code.
|
||||||
|
*/
|
||||||
|
public static void init() {
|
||||||
|
try {
|
||||||
|
// Create the map
|
||||||
|
for (String mapName : Maps) {
|
||||||
|
// Create a graph reader
|
||||||
|
final GraphReader reader = new BinaryGraphReader(
|
||||||
|
new DataInputStream(new BufferedInputStream(new FileInputStream(mapName))));
|
||||||
|
// Read the graph.
|
||||||
|
graph.add(reader.read());
|
||||||
|
// free resources
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException e) {
|
||||||
|
System.err.println("File not found: " + e.getMessage());
|
||||||
|
fail("File not found: " + e.getMessage());
|
||||||
|
}
|
||||||
|
catch (IOException e ) {
|
||||||
|
System.err.println("Error reading file: " + e.getMessage());
|
||||||
|
fail("Error reading file: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Stratégie:
|
||||||
|
* Chemins courts testés par comparaison avec Bellman.
|
||||||
|
* Chemin longs testés par comparaison avec chemins déjà construits. Bellman trop long.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verifies that path is valid and mathes the one found by the Bellman algo
|
||||||
|
*/
|
||||||
|
private void assertBellmanHasSameResult(Graph graph, Node origin, Node destination, ArcInspector arcFilter) {
|
||||||
|
final ShortestPathData data = new ShortestPathData(graph, origin, destination, arcFilter);
|
||||||
|
|
||||||
|
final ShortestPathAlgorithm algo = initAlgo(data);
|
||||||
|
final ShortestPathSolution path = algo.doRun();
|
||||||
|
|
||||||
|
final BellmanFordAlgorithm bellman = new BellmanFordAlgorithm(data);
|
||||||
|
final ShortestPathSolution bell_path = bellman.doRun();
|
||||||
|
|
||||||
|
assert(path.getPath().isValid());
|
||||||
|
assert(path.isFeasible());
|
||||||
|
assert(Math.abs(algo.getCostPath() - path.getPath().getLength()) < 1.0);
|
||||||
|
assert(Math.abs(path.getPath().getLength() - bell_path.getPath().getLength()) < 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verifies that no path is found
|
||||||
|
*/
|
||||||
|
private void assertNoPathFound(Graph graph, Node origin, Node destination, ArcInspector arcFilter) {
|
||||||
|
ShortestPathData data = new ShortestPathData(graph, origin, destination, arcFilter);
|
||||||
|
|
||||||
|
final ShortestPathAlgorithm algo = initAlgo(data);
|
||||||
|
final ShortestPathSolution path = algo.doRun();
|
||||||
|
|
||||||
|
assert(!path.isFeasible());
|
||||||
|
assert(path.getPath() == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
/*
|
||||||
|
* Map: carre.mapgr
|
||||||
|
* Chemin: 19 --> 4
|
||||||
|
* Tous chemins permis
|
||||||
|
* Mode: LENGTH
|
||||||
|
* PATH UTILISE : ../Paths/custom_paths/short_path_carre.path
|
||||||
|
*/
|
||||||
|
public void chemin_court_CARRE_length() {
|
||||||
|
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0); // all arcs
|
||||||
|
Graph myGraph = graph.get(0);
|
||||||
|
Node origin = myGraph.get(19);
|
||||||
|
Node destination = myGraph.get(4);
|
||||||
|
|
||||||
|
assertBellmanHasSameResult(myGraph, origin, destination, arcInspector);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
/*
|
||||||
|
* Chemin long relativement à la carte carrée.
|
||||||
|
* Chemin: 15 --> 9
|
||||||
|
* Tous chemins permis
|
||||||
|
* PATH UTILISE : ../Paths/custom_paths/long_path_carre.path
|
||||||
|
*/
|
||||||
|
public void chemin_long_CARRE_length() {
|
||||||
|
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0);
|
||||||
|
Graph myGraph = graph.get(0);
|
||||||
|
Node origin = myGraph.get(15);
|
||||||
|
Node destination = myGraph.get(9);
|
||||||
|
|
||||||
|
assertBellmanHasSameResult(myGraph, origin, destination, arcInspector);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
/*
|
||||||
|
* Chemin nul sur carte carrée.
|
||||||
|
* L'origine et la destination sont les mêmes (noeud 3).
|
||||||
|
* Tous chemins permis
|
||||||
|
*/
|
||||||
|
public void chemin_nul_CARRE() {
|
||||||
|
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0);
|
||||||
|
Graph myGraph = graph.get(0);
|
||||||
|
Node origin = myGraph.get(3);
|
||||||
|
Node destination = myGraph.get(3);
|
||||||
|
|
||||||
|
assertNoPathFound(myGraph, origin, destination, arcInspector);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
/*
|
||||||
|
* Chemin inexistant sur la carte INSA.
|
||||||
|
* Origine: 224
|
||||||
|
* Destination: 814.
|
||||||
|
* Les 2 noeuds font partie de deux composantes non connexes.
|
||||||
|
* Tous chemins permis.
|
||||||
|
*/
|
||||||
|
public void chemin_inexistant_INSA() {
|
||||||
|
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0);
|
||||||
|
Graph myGraph = graph.get(1);
|
||||||
|
Node origin = myGraph.get(224);
|
||||||
|
Node destination = myGraph.get(814);
|
||||||
|
|
||||||
|
assertNoPathFound(myGraph, origin, destination, arcInspector);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
/*
|
||||||
|
* Chemin court sur la carte de Toulouse.
|
||||||
|
* Origine : 8423
|
||||||
|
* Destination: 8435
|
||||||
|
* Tous chemins permis.
|
||||||
|
* PATH UTILISE : ../Paths/custom_paths/short_path_tls.path
|
||||||
|
*/
|
||||||
|
public void chemin_court_TLS() {
|
||||||
|
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0);
|
||||||
|
Graph myGraph = graph.get(2);
|
||||||
|
Node origin = myGraph.get(8423);
|
||||||
|
Node destination = myGraph.get(8435);
|
||||||
|
|
||||||
|
assertBellmanHasSameResult(myGraph, origin, destination, arcInspector);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
/*
|
||||||
|
* Chemin long sur la carte de Toulouse.
|
||||||
|
* Même si Bellman est de plus long à faire long à faire, ce test prend moins
|
||||||
|
* de 3s, on estime que ce n'est pas trop et on va utiliser Bellman.
|
||||||
|
* Par contre, dans le test sur la région midi_pyrenees qui arrive après, on va
|
||||||
|
* être obligé de trouver une autre solution.
|
||||||
|
* Origine: 16644
|
||||||
|
* Destination: 39229
|
||||||
|
* Mode: LENGTH
|
||||||
|
* PATH UTILISE : ../Paths/custom_paths/long_path_tls.path
|
||||||
|
*/
|
||||||
|
public void chemin_long_TLS_length() {
|
||||||
|
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0);
|
||||||
|
Graph myGraph = graph.get(2);
|
||||||
|
Node origin = myGraph.get(16644);
|
||||||
|
Node destination = myGraph.get(39229);
|
||||||
|
|
||||||
|
assertBellmanHasSameResult(myGraph, origin, destination, arcInspector);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
/*
|
||||||
|
* Chemin long sur la carte de Toulouse.
|
||||||
|
* Même si Bellman est de plus long à faire long à faire, ce test prend moins
|
||||||
|
* de 3s, on estime que ce n'est pas trop et on va utiliser Bellman.
|
||||||
|
* Par contre, dans le test sur la région midi_pyrenees qui arrive après, on va
|
||||||
|
* être obligé de trouver une autre solution.
|
||||||
|
* Origine: 16644
|
||||||
|
* Destination: 39229
|
||||||
|
* Mode: TIME
|
||||||
|
* PATH UTILISE : ../Paths/custom_paths/long_path_tls.path
|
||||||
|
*/
|
||||||
|
public void chemin_long_TLS_time() {
|
||||||
|
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(2);
|
||||||
|
Graph myGraph = graph.get(2);
|
||||||
|
Node origin = myGraph.get(16644);
|
||||||
|
Node destination = myGraph.get(39229);
|
||||||
|
ShortestPathData data = new ShortestPathData(myGraph, origin, destination, arcInspector);
|
||||||
|
|
||||||
|
final ShortestPathAlgorithm algo = initAlgo(data);
|
||||||
|
final ShortestPathSolution path = algo.doRun();
|
||||||
|
|
||||||
|
BellmanFordAlgorithm bellman = new BellmanFordAlgorithm(data);
|
||||||
|
ShortestPathSolution bell_path = bellman.doRun();
|
||||||
|
|
||||||
|
assert(path.getPath().isValid());
|
||||||
|
assert(path.isFeasible());
|
||||||
|
assert((Math.abs(algo.getCostPath() - path.getPath().getMinimumTravelTime()) < 1.0));
|
||||||
|
assert(Math.abs(path.getPath().getMinimumTravelTime() - bell_path.getPath().getMinimumTravelTime()) < 10.0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
/*
|
||||||
|
* Test du mode à vélo facultatif.
|
||||||
|
* Nous prenons une origine sur l'autoroute et une destination en dehors.
|
||||||
|
* Ce chemin est donc censé être utilisable en vélo mais pas en voiture.
|
||||||
|
* Avec le filtre vélos, on obtient pas de chemin.
|
||||||
|
* Avec le filtre voitures on obtient un chemin.
|
||||||
|
* Origine: 19135
|
||||||
|
* Destination: 1980
|
||||||
|
* PATH UTILISE : ../Paths/custom_paths/path_cyclist.path
|
||||||
|
*/
|
||||||
|
public void chemin_velo_uniquement() {
|
||||||
|
// Filter: forBicyclesCustomT
|
||||||
|
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(4);
|
||||||
|
|
||||||
|
Graph myGraph = graph.get(2);
|
||||||
|
Node origin = myGraph.get(19135);
|
||||||
|
Node destination = myGraph.get(1980);
|
||||||
|
|
||||||
|
ShortestPathData data = new ShortestPathData(myGraph, origin, destination, arcInspector);
|
||||||
|
|
||||||
|
ShortestPathAlgorithm algo_bicycle = initAlgo(data);
|
||||||
|
ShortestPathSolution path_bicycle = algo_bicycle.doRun();
|
||||||
|
|
||||||
|
BellmanFordAlgorithm bellman_bicycle = new BellmanFordAlgorithm(data);
|
||||||
|
ShortestPathSolution bell_path_bicycle = bellman_bicycle.doRun();
|
||||||
|
|
||||||
|
// Filter: forCarsL
|
||||||
|
ArcInspector new_Inspector = ArcInspectorFactory.getAllFilters().get(1);
|
||||||
|
data = new ShortestPathData(myGraph, origin, destination, new_Inspector);
|
||||||
|
|
||||||
|
ShortestPathAlgorithm algo_car = initAlgo(data);
|
||||||
|
ShortestPathSolution path_car = algo_car.doRun();
|
||||||
|
|
||||||
|
assertEquals(path_bicycle.getPath(), null);
|
||||||
|
assert(!path_bicycle.isFeasible());
|
||||||
|
assertEquals(bell_path_bicycle.getPath(), null);
|
||||||
|
assert(!bell_path_bicycle.isFeasible());
|
||||||
|
|
||||||
|
assert(path_car.getPath() != null);
|
||||||
|
assert(path_car.isFeasible());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
/*
|
||||||
|
* On veut vérifier le bon fonctionnement des modes TIME et LENGTH.
|
||||||
|
* Pour cela, on va obtenir deux chemins avec l'algo de algo et vérifier
|
||||||
|
* que:
|
||||||
|
* -le chemin TIME est plus rapide en durée que le chemin LENGTH
|
||||||
|
* -le chemin LENGTH est plus court en distance que le chemin LENGTH.
|
||||||
|
* On prend un grand chemin pour être sur d'avoir une différence :
|
||||||
|
* Origine: 16644
|
||||||
|
* Destination: 39229
|
||||||
|
* Mode: TIME/LENGTH
|
||||||
|
* PATH UTILISE : ../Paths/custom_paths/long_path_tls.path
|
||||||
|
*/
|
||||||
|
public void chemin_time_length_comparison() {
|
||||||
|
Graph myGraph = graph.get(2);
|
||||||
|
Node origin = myGraph.get(19135);
|
||||||
|
Node destination = myGraph.get(1980);
|
||||||
|
|
||||||
|
// Filter: forCarsL
|
||||||
|
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(1);
|
||||||
|
ShortestPathData data = new ShortestPathData(myGraph, origin, destination, arcInspector);
|
||||||
|
|
||||||
|
ShortestPathAlgorithm algo_L = initAlgo(data);
|
||||||
|
ShortestPathSolution path_L = algo_L.doRun();
|
||||||
|
|
||||||
|
// Filter: forCarsT
|
||||||
|
ArcInspector new_Inspector = ArcInspectorFactory.getAllFilters().get(2);
|
||||||
|
data = new ShortestPathData(myGraph, origin, destination, new_Inspector);
|
||||||
|
|
||||||
|
ShortestPathAlgorithm algo_T = initAlgo(data);
|
||||||
|
ShortestPathSolution path_T = algo_T.doRun();
|
||||||
|
|
||||||
|
assert(path_L.getPath().isValid());
|
||||||
|
assert(path_L.isFeasible());
|
||||||
|
assert(path_T.getPath().isValid());
|
||||||
|
assert(path_T.isFeasible());
|
||||||
|
|
||||||
|
assert((Math.abs(algo_L.getCostPath() - path_L.getPath().getLength()) < 1.0));
|
||||||
|
assert((Math.abs(algo_T.getCostPath() - path_T.getPath().getMinimumTravelTime()) < 1.0));
|
||||||
|
|
||||||
|
assert(path_L.getPath().getLength() < path_T.getPath().getLength());
|
||||||
|
assert(path_L.getPath().getMinimumTravelTime() > path_T.getPath().getMinimumTravelTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
/*
|
||||||
|
* Cette fois-ci, Bellman est trop long à utiliser même une seule fois.
|
||||||
|
* On va donc utiliser quelques techniques pour se rassurer.
|
||||||
|
* -vérifier certains noeuds comme départ, destination, noeud pivot.
|
||||||
|
* -vérifier le cout avec une estimation gentille.
|
||||||
|
* -etc.
|
||||||
|
* Origin: 279654
|
||||||
|
* Destination: 481936
|
||||||
|
* Mode: LENGTH
|
||||||
|
* PATH UTILISE : ../Paths/custom_paths/long_chemin_midi_pyrenees.path
|
||||||
|
*/
|
||||||
|
public void chemin_long_Midi_pyrenees_length() {
|
||||||
|
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0);
|
||||||
|
Graph myGraph = graph.get(3);
|
||||||
|
Node origin = myGraph.get(279654);
|
||||||
|
Node destination = myGraph.get(481936);
|
||||||
|
ShortestPathData data = new ShortestPathData(myGraph, origin, destination, arcInspector);
|
||||||
|
|
||||||
|
final ShortestPathAlgorithm algo = initAlgo(data);
|
||||||
|
final ShortestPathSolution path = algo.doRun();
|
||||||
|
|
||||||
|
assert(path.getPath().isValid());
|
||||||
|
assert(path.isFeasible());
|
||||||
|
// On a des erreurs d'arrondi assez grande avec la distance, mais elles sont mineures
|
||||||
|
// relativement aux distance de 300000 ici.
|
||||||
|
assert((Math.abs(algo.getCostPath() - path.getPath().getLength())) < 1000.0);
|
||||||
|
// Selon le chemin sélectionné on peut avoir une estimation de la longueur qu'on est censée avoir.
|
||||||
|
// Avec notre long chemin: entre 250 et 260 kilomètres.
|
||||||
|
assert(algo.getCostPath() > 250000 && algo.getCostPath() < 260000);
|
||||||
|
// On peut aussi supposer que le nombre d'arcs empruntés est très grand.
|
||||||
|
assert(path.getPath().getArcs().size() > 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
/*
|
||||||
|
* Cette fois-ci, Bellman est trop long à utiliser même une seule fois.
|
||||||
|
* On va donc utiliser quelques techniques pour se rassurer.
|
||||||
|
* -vérifier certains noeuds comme départ, destination, noeud pivot.
|
||||||
|
* -vérifier le cout avec une estimation gentille.
|
||||||
|
* -etc.
|
||||||
|
* Origin: 279654
|
||||||
|
* Destination: 481936
|
||||||
|
* Mode: LENGTH
|
||||||
|
* PATH UTILISE : ../Paths/custom_paths/long_chemin_midi_pyrenees.path
|
||||||
|
*/
|
||||||
|
public void chemin_long_Midi_pyrenees_time() {
|
||||||
|
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(2);
|
||||||
|
Graph myGraph = graph.get(3);
|
||||||
|
Node origin = myGraph.get(279654);
|
||||||
|
Node destination = myGraph.get(481936);
|
||||||
|
ShortestPathData data = new ShortestPathData(myGraph, origin, destination, arcInspector);
|
||||||
|
|
||||||
|
final ShortestPathAlgorithm algo = initAlgo(data);
|
||||||
|
final ShortestPathSolution path = algo.doRun();
|
||||||
|
|
||||||
|
assert(path.getPath().isValid());
|
||||||
|
assert(path.isFeasible());
|
||||||
|
// On a des erreurs d'arrondi assez grandes avec la distance
|
||||||
|
assert((Math.abs(algo.getCostPath() - path.getPath().getMinimumTravelTime())) < 100.0);
|
||||||
|
// Selon le chemin sélectionné on peut avoir une estimation de la durée qu'on est censée avoir.
|
||||||
|
// Avec notre long chemin: entre 12000 et 13000 secondes.
|
||||||
|
assert(algo.getCostPath() > 12000 && algo.getCostPath() < 13000);
|
||||||
|
// On peut aussi supposer que le nombre d'arcs empruntés est très grand.
|
||||||
|
assert(path.getPath().getArcs().size() > 1000);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue