A* + tests Dijkstra et A*

This commit is contained in:
Cavailles Kevin 2020-05-13 18:18:35 +02:00
parent 5c9a41dd1d
commit a95084f21e
10 changed files with 440 additions and 7 deletions

View file

@ -1,9 +1,74 @@
package org.insa.graphs.algorithm.shortestpath;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import org.insa.graphs.algorithm.AbstractInputData.Mode;
import org.insa.graphs.algorithm.AbstractSolution.Status;
import org.insa.graphs.algorithm.utils.BinaryHeap;
import org.insa.graphs.model.Arc;
import org.insa.graphs.model.Graph;
import org.insa.graphs.model.Node;
import org.insa.graphs.model.Path;
import org.insa.graphs.model.Point;
public class AStarAlgorithm extends DijkstraAlgorithm {
public AStarAlgorithm(ShortestPathData data) {
super(data);
}
@Override
protected Label createLabel(ShortestPathData data, Arc pere, Label noeudPrecedent) {
if(pere == null && noeudPrecedent == null) {
return new LabelStar(data.getOrigin(),
0,
Point.distance(data.getOrigin().getPoint(), data.getDestination().getPoint() ) ,
null);
}
double coutEstime = 0;
//Cas chemin le plus court
if(data.getMode() == Mode.LENGTH) {
coutEstime = pere.getDestination().getPoint().distanceTo(data.getDestination().getPoint() );
//Cas chemin le plus rapide
}else if(data.getMode() == Mode.TIME) {
int vitesse,
vitesseGraph = data.getGraph().getGraphInformation().getMaximumSpeed() ,
vitesseArc = data.getMaximumSpeed() ;
//On récupère la vitesse
if(data.getGraph().getGraphInformation().hasMaximumSpeed() && vitesseArc !=-1 ) {
vitesse = Math.min(vitesseGraph, vitesseArc);
}else {
if(data.getGraph().getGraphInformation().hasMaximumSpeed() && vitesseArc == -1) {
vitesse = vitesseGraph;
}else if( !data.getGraph().getGraphInformation().hasMaximumSpeed() && vitesseArc !=-1) {
vitesse = vitesseArc;
}else{
vitesse = 1;
}
}
coutEstime = pere.getDestination().getPoint().distanceTo(data.getDestination().getPoint()) * 3.6f / vitesse;
}else {
return null;
}
return new LabelStar(pere.getDestination(),
noeudPrecedent.getCost() + data.getCost(pere),
coutEstime,
pere);
}
}

View file

@ -31,7 +31,7 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
Label labels[] = new Label[graph.getNodes().size()];
Arrays.fill(labels, null);
Label origine = new Label(data.getOrigin(), 0 , null);
Label origine = createLabel(data, null, null);
labels[data.getOrigin().getId()] = origine;
tas.insert(origine);
@ -69,6 +69,9 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
minimum.setMark();
notifyNodeMarked(minimum.getCurrent());
// System.out.println(minimum.getTotalCost());
// System.out.println(minimum.getCurrent().getNumberOfSuccessors());
//Pour chaque successeurs du noeud minimum
@ -83,14 +86,14 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
//Si le successeur n'existe pas, on le crée
if(successeur == null) {
successeur = new Label(arc.getDestination(), minimum.getCost() + data.getCost(arc), arc);
successeur = this.createLabel(data, arc, minimum);
labels[arc.getDestination().getId()] = successeur;
tas.insert(successeur);
notifyNodeReached(successeur.getCurrent());
//Sinon on regarde si on peut optimiser le coût du successeur
}else {
}else{
if(successeur.getCost() > minimum.getCost() + data.getCost(arc)) {
successeur.setCost(minimum.getCost() + data.getCost(arc));
successeur.setFather(arc);
@ -98,7 +101,7 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
try {
tas.miseAJour(successeur);
}catch(Exception e) {
System.out.println("fatal error");
}
}
@ -135,5 +138,14 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
System.out.println("nb erreurs = "+cptErreurs);
return solution;
}
protected Label createLabel(ShortestPathData data, Arc pere, Label noeudPrecedent) {
if(pere != null && noeudPrecedent != null) {
return new Label( pere.getDestination() , noeudPrecedent.getCost()+ data.getCost(pere), pere);
}else {
return new Label(data.getOrigin(), 0, null);
}
}
}

View file

@ -46,8 +46,13 @@ public class Label implements Comparable<Label>{
public String toString() {
return ""+this.getCost();
}
public double getTotalCost() {
return this.cout;
}
@Override
public int compareTo(Label o) {
return Double.compare(this.getCost(), o.getCost());
return Double.compare(this.getTotalCost(), o.getTotalCost());
}
}

View file

@ -0,0 +1,19 @@
package org.insa.graphs.algorithm.shortestpath;
import org.insa.graphs.model.Arc;
import org.insa.graphs.model.Node;
public class LabelStar extends Label{
private Double coutEstime;
public LabelStar(Node sommetCourant, double cout, double coutEstime, Arc pere) {
super(sommetCourant, cout, pere);
this.coutEstime = coutEstime;
}
@Override
public double getTotalCost(){
return this.getCost() + this.coutEstime;
}
}

View file

@ -230,6 +230,7 @@ public class BinaryHeap<E extends Comparable<E>> implements PriorityQueue<E> {
}
public boolean isValid() {
E current;
E parent;

View file

@ -0,0 +1,107 @@
package org.insa.graphs.algorithm.shortestpath;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.List;
import org.insa.graphs.algorithm.AbstractSolution.Status;
import org.insa.graphs.algorithm.shortestpath.AStarAlgorithm;
import org.insa.graphs.algorithm.shortestpath.DijkstraAlgorithm;
import org.insa.graphs.algorithm.shortestpath.ShortestPathSolution;
import org.insa.graphs.model.Arc;
import org.insa.graphs.model.Graph;
import org.insa.graphs.model.Node;
import org.insa.graphs.model.Path;
import org.junit.After;
import org.junit.Test;
public class AStarAlgorithmTest extends algorithmTest{
@After
public void tearDown() throws Exception {
}
@Test
public void testAStarShortest() {
for(int i=0; i<dataShortest.length; i++) {
AStarAlgorithm aStar = new AStarAlgorithm(dataShortest[i]);
ShortestPathSolution solution = aStar.run();
Path cheminSolution = solution.getPath();
Graph graph = solution.getInputData().getGraph();
//Vérifie chemin valide
assertTrue(cheminSolution.isValid());
assertEquals(cheminSolution.getOrigin(), graph.get(tabOrigin[i]));
assertEquals(cheminSolution.getDestination(), graph.get(tabDestination[i]));
// List of nodes
ArrayList<Node> nodes = new ArrayList<Node>();
List<Arc> arcsSolution = cheminSolution.getArcs();
nodes.add(arcsSolution.get(0).getOrigin());
for(int j=0;j<arcsSolution.size(); j++) {
nodes.add(arcsSolution.get(j).getDestination());
}
Path cheminShortest = Path.createShortestPathFromNodes(graph, nodes);
//Vérifie que les chemins sont identiques (Arcs, taille, temps)
assertEquals(cheminSolution.getArcs(), cheminShortest.getArcs());
assertTrue(cheminSolution.getLength() == cheminShortest.getLength());
assertTrue(cheminSolution.getMinimumTravelTime() == cheminShortest.getMinimumTravelTime());
}
}
@Test
public void testAStarFastest() {
for(int i=0; i<dataShortest.length; i++) {
AStarAlgorithm aStar = new AStarAlgorithm(dataFastest[i]);
ShortestPathSolution solution = aStar.run();
Path cheminSolution = solution.getPath();
Graph graph = solution.getInputData().getGraph();
//Vérifie chemin valide
assertTrue(cheminSolution.isValid());
assertEquals(cheminSolution.getOrigin(), graph.get(tabOrigin[i]));
assertEquals(cheminSolution.getDestination(), graph.get(tabDestination[i]));
// List of nodes
ArrayList<Node> nodes = new ArrayList<Node>();
List<Arc> arcsSolution = cheminSolution.getArcs();
nodes.add(arcsSolution.get(0).getOrigin());
for(int j=0;j<arcsSolution.size(); j++) {
nodes.add(arcsSolution.get(j).getDestination());
}
Path cheminFastest = Path.createFastestPathFromNodes(graph, nodes);
//Vérifie que les chemins sont identiques (Arcs, taille, temps)
assertEquals(cheminSolution.getArcs(), cheminFastest.getArcs());
assertTrue(cheminSolution.getLength() == cheminFastest.getLength());
assertTrue(cheminSolution.getMinimumTravelTime() == cheminFastest.getMinimumTravelTime());
}
}
@Test
public void testDijkstraInfeasable() {
AStarAlgorithm aStar = new AStarAlgorithm(dataInfeasable);
ShortestPathSolution solution = aStar.run();
Path cheminSolution = solution.getPath();
//Vérifie chemin valide
assertEquals(cheminSolution, null);
assertEquals(solution.getStatus(), Status.INFEASIBLE);
}
}

View file

@ -0,0 +1,127 @@
package org.insa.graphs.algorithm.shortestpath;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
import org.insa.graphs.algorithm.ArcInspector;
import org.insa.graphs.algorithm.ArcInspectorFactory;
import org.insa.graphs.algorithm.AbstractSolution.Status;
import org.insa.graphs.algorithm.shortestpath.DijkstraAlgorithm;
import org.insa.graphs.algorithm.shortestpath.ShortestPathData;
import org.insa.graphs.algorithm.shortestpath.ShortestPathSolution;
import org.insa.graphs.model.Arc;
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.BinaryPathReader;
import org.insa.graphs.model.io.GraphReader;
import org.insa.graphs.model.io.PathReader;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class DijkstraAlgorithmTest extends algorithmTest {
// Small graph use for tests
@After
public void tearDown() throws Exception {
}
@Test
public void testDijkstraShortest() {
for(int i=0; i<dataShortest.length; i++) {
DijkstraAlgorithm dijkstra = new DijkstraAlgorithm(dataShortest[i]);
ShortestPathSolution solution = dijkstra.run();
Path cheminSolution = solution.getPath();
Graph graph = solution.getInputData().getGraph();
//Vérifie chemin valide
assertTrue(cheminSolution.isValid());
assertEquals(cheminSolution.getOrigin(), graph.get(tabOrigin[i]));
assertEquals(cheminSolution.getDestination(), graph.get(tabDestination[i]));
// List of nodes
ArrayList<Node> nodes = new ArrayList<Node>();
List<Arc> arcsSolution = cheminSolution.getArcs();
nodes.add(arcsSolution.get(0).getOrigin());
for(int j=0;j< arcsSolution.size(); j++) {
nodes.add(arcsSolution.get(j).getDestination());
}
Path cheminShortest = Path.createShortestPathFromNodes(graph, nodes);
//Vérifie que les chemins sont identiques (Arcs, taille, temps)
assertEquals(cheminSolution.getArcs(), cheminShortest.getArcs());
assertTrue(cheminSolution.getLength() == cheminShortest.getLength());
assertTrue(cheminSolution.getMinimumTravelTime() == cheminShortest.getMinimumTravelTime());
}
}
@Test
public void testDijkstraFastest() {
for(int i=0; i<dataShortest.length; i++) {
DijkstraAlgorithm dijkstra = new DijkstraAlgorithm(dataFastest[i]);
ShortestPathSolution solution = dijkstra.run();
Path cheminSolution = solution.getPath();
Graph graph = solution.getInputData().getGraph();
//Vérifie chemin valide
assertTrue(cheminSolution.isValid());
assertEquals(cheminSolution.getOrigin(), graph.get(tabOrigin[i]));
assertEquals(cheminSolution.getDestination(), graph.get(tabDestination[i]));
// List of nodes
ArrayList<Node> nodes = new ArrayList<Node>();
List<Arc> arcsSolution = cheminSolution.getArcs();
nodes.add(arcsSolution.get(0).getOrigin());
for(int j=0; j<arcsSolution.size(); j++) {
nodes.add(arcsSolution.get(j).getDestination());
}
Path cheminFastest = Path.createFastestPathFromNodes(graph, nodes);
//Vérifie que les chemins sont identiques (Arcs, taille, temps)
assertEquals(cheminSolution.getArcs(), cheminFastest.getArcs());
assertTrue(cheminSolution.getLength() == cheminFastest.getLength());
assertTrue(cheminSolution.getMinimumTravelTime() == cheminFastest.getMinimumTravelTime());
}
}
@Test
public void testDijkstraInfeasable() {
DijkstraAlgorithm dijkstra = new DijkstraAlgorithm(dataInfeasable);
ShortestPathSolution solution = dijkstra.run();
Path cheminSolution = solution.getPath();
//Vérifie chemin valide
assertEquals(cheminSolution, null);
assertEquals(solution.getStatus(), Status.INFEASIBLE);
}
}

View file

@ -0,0 +1,96 @@
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.util.List;
import org.insa.graphs.algorithm.ArcInspector;
import org.insa.graphs.algorithm.ArcInspectorFactory;
import org.insa.graphs.algorithm.shortestpath.ShortestPathData;
import org.insa.graphs.model.Graph;
import org.insa.graphs.model.io.BinaryGraphReader;
import org.insa.graphs.model.io.GraphReader;
import org.junit.After;
import org.junit.Before;
public class algorithmTest {
protected Graph graph, graphPolynesie, graphBelgique;
final String hauteGaronne = "/Users/Kevin/Desktop/programmation/java_files/Maps/europe/france/haute-garonne.mapgr";
final String polynesie = "/Users/Kevin/Desktop/programmation/java_files/Maps/europe/france/french-polynesia.mapgr";
final String belgique = "/Users/Kevin/Desktop/programmation/java_files/Maps/europe/belgique/belgium.mapgr";
final static int taille = 5;
protected ShortestPathData dataShortest[];
protected ShortestPathData dataFastest[];
protected ShortestPathData dataInfeasable;
protected int tabOrigin[], tabDestination[];
@Before
public void setUp() throws Exception {
List<ArcInspector> arcList = ArcInspectorFactory.getAllFilters();
ArcInspector arcShortestAllRoad = arcList.get(0);
ArcInspector arcFastestAllRoad = arcList.get(2);
try (GraphReader readerHauteGaronne = new BinaryGraphReader(new DataInputStream(
new BufferedInputStream(new FileInputStream(hauteGaronne))))) {
// TODO: Read the graph.
graph = readerHauteGaronne.read();
}
try (GraphReader readerPolynesie = new BinaryGraphReader(new DataInputStream(
new BufferedInputStream(new FileInputStream(polynesie))))) {
// TODO: Read the graph.
graphPolynesie = readerPolynesie.read();
}
try (GraphReader readerBelgique = new BinaryGraphReader(new DataInputStream(
new BufferedInputStream(new FileInputStream(belgique))))) {
// TODO: Read the graph.
graphBelgique = readerBelgique.read();
}
dataShortest = new ShortestPathData[taille];
dataFastest = new ShortestPathData[taille];
tabOrigin = new int[taille]; tabDestination = new int[taille];
tabOrigin[0] = 10991; tabOrigin[1] = 102582; tabOrigin[2]= 81460; tabOrigin[3]= 942294; tabOrigin[4]= 10228;
tabDestination[0] = 89149; tabDestination[1]= 84718; tabDestination[2] = 129594; tabDestination[3] = 412806 ; tabDestination[4]= 666164 ;
dataShortest[0] = new ShortestPathData(graph, graph.get(tabOrigin[0]), graph.get(tabDestination[0]), arcShortestAllRoad);
dataShortest[1] = new ShortestPathData(graph, graph.get(tabOrigin[1]), graph.get(tabDestination[1]), arcShortestAllRoad);
dataShortest[2] = new ShortestPathData(graph, graph.get(tabOrigin[2]), graph.get(tabDestination[2]), arcShortestAllRoad);
dataShortest[3] = new ShortestPathData(graphBelgique, graphBelgique.get(tabOrigin[3]), graphBelgique.get(tabDestination[3]), arcShortestAllRoad);
dataShortest[4] = new ShortestPathData(graphBelgique, graphBelgique.get(tabOrigin[4]), graphBelgique.get(tabDestination[4]), arcShortestAllRoad);
dataFastest[0] = new ShortestPathData(graph, graph.get(tabOrigin[0]), graph.get(tabDestination[0]) , arcFastestAllRoad);
dataFastest[1] = new ShortestPathData(graph, graph.get(tabOrigin[1]), graph.get(tabDestination[1]), arcFastestAllRoad);
dataFastest[2] = new ShortestPathData(graph, graph.get(tabOrigin[2]), graph.get(tabDestination[2]), arcFastestAllRoad);
dataFastest[3] = new ShortestPathData(graphBelgique, graphBelgique.get(tabOrigin[3]), graphBelgique.get(tabDestination[3]), arcFastestAllRoad);
dataFastest[4] = new ShortestPathData(graphBelgique, graphBelgique.get(tabOrigin[4]), graphBelgique.get(tabDestination[4]), arcFastestAllRoad);
dataInfeasable = new ShortestPathData(graphPolynesie, graphPolynesie.get(2984), graphPolynesie.get(10467), arcFastestAllRoad);
}
@After
public void tearDown() throws Exception {
}
}

View file

@ -499,6 +499,7 @@ public class MainWindow extends JFrame {
}
}
}
Runnable runnable = null;

View file

@ -183,7 +183,7 @@ public class GraphStatistics {
* @return true if this graph has a maximum speed limit, false otherwise.
*/
public boolean hasMaximumSpeed() {
return this.maximumLength != NO_MAXIMUM_SPEED;
return this.maximumSpeed != NO_MAXIMUM_SPEED;
}
/**