Version Fonctionnelle : A* implémenté (copie du code de Dijkstra)
This commit is contained in:
parent
7c91d40de9
commit
410f1c9a6e
3 changed files with 191 additions and 2 deletions
|
@ -1,9 +1,161 @@
|
|||
package org.insa.graphs.algorithm.shortestpath;
|
||||
|
||||
import org.insa.graphs.model.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.insa.graphs.algorithm.AbstractInputData.Mode;
|
||||
import org.insa.graphs.algorithm.AbstractSolution.Status;
|
||||
import org.insa.graphs.algorithm.utils.*;
|
||||
|
||||
public class AStarAlgorithm extends DijkstraAlgorithm {
|
||||
|
||||
public AStarAlgorithm(ShortestPathData data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ShortestPathSolution doRun() {
|
||||
|
||||
BinaryHeap<Label> tas = new BinaryHeap<Label>();
|
||||
|
||||
final ShortestPathData data = getInputData();
|
||||
|
||||
Graph graph = data.getGraph();
|
||||
Node origin = data.getOrigin();
|
||||
Node dest = data.getDestination();
|
||||
int nbNodes = graph.size();
|
||||
|
||||
LabelStar[] labels = new LabelStar[nbNodes];
|
||||
//int nbNonMarque = nbNodes;
|
||||
int MaxSpeed = data.getMaximumSpeed();
|
||||
if (data.getMode() == Mode.LENGTH) {
|
||||
MaxSpeed = 1;
|
||||
}
|
||||
|
||||
for (Node node: graph.getNodes()) {
|
||||
double estimation = Point.distance(node.getPoint(), dest.getPoint())/MaxSpeed;
|
||||
labels[node.getId()] = new LabelStar(node, estimation);
|
||||
}
|
||||
|
||||
labels[origin.getId()].actualiser(0.0, null);
|
||||
tas.insert(labels[origin.getId()]);
|
||||
notifyOriginProcessed(origin);
|
||||
|
||||
boolean encore = true;
|
||||
|
||||
while ((!labels[dest.getId()].isMarque()) && encore) {
|
||||
|
||||
try {
|
||||
Label current = tas.deleteMin();
|
||||
|
||||
int currentID = current.getSommetCourant().getId();
|
||||
labels[currentID].marquer();
|
||||
notifyNodeMarked(current.getSommetCourant());
|
||||
|
||||
// POUR LE TEST SUR LES COUTS CROISSANTS
|
||||
// System.out.println(labels[currentID].getCost());
|
||||
|
||||
//nbNonMarque--;
|
||||
|
||||
// POUR LE TEST SUR LES SUCCESSEURS
|
||||
//int compteur_successeurs = 0;
|
||||
for (Arc succ: labels[currentID].getSommetCourant().getSuccessors()) {
|
||||
// POUR LE TEST SUR LES SUCCESSEURS
|
||||
//compteur_successeurs++;
|
||||
if (!data.isAllowed(succ)) {
|
||||
continue;
|
||||
}
|
||||
int succID = succ.getDestination().getId();
|
||||
if (!labels[succID].isMarque()) {
|
||||
if (labels[succID].getCost() > (labels[currentID].getCost() + data.getCost(succ))) {
|
||||
if (labels[succID].getCost() < Double.POSITIVE_INFINITY) {
|
||||
tas.remove(labels[succID]);
|
||||
} else {
|
||||
notifyNodeReached(succ.getDestination());
|
||||
}
|
||||
labels[succID].actualiser(labels[currentID].getCost() + data.getCost(succ), succ);
|
||||
tas.insert(labels[succID]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// POUR LE TEST SUR LES SUCCESSEURS
|
||||
/*if (compteur_successeurs != labels[currentID].getSommetCourant().getNumberOfSuccessors()) {
|
||||
System.out.println("ERREUR Nombre de successeurs visités : " + compteur_successeurs + "/" + labels[currentID].getSommetCourant().getNumberOfSuccessors());
|
||||
}
|
||||
System.out.println("Nombre de successeurs visités : " + compteur_successeurs + "/" + labels[currentID].getSommetCourant().getNumberOfSuccessors());
|
||||
*/
|
||||
}
|
||||
catch (EmptyPriorityQueueException e) {
|
||||
encore = false;
|
||||
}
|
||||
catch (ElementNotFoundException e) {
|
||||
encore = false;
|
||||
}
|
||||
}
|
||||
|
||||
ShortestPathSolution solution = null;
|
||||
//Pour le test SOMME(couts) = Cout(Label(Destination))
|
||||
double SommeCouts = 0.0;
|
||||
|
||||
// Destination has no predecessor, the solution is infeasible...
|
||||
if (labels[dest.getId()].getPere() == null) {
|
||||
solution = new ShortestPathSolution(data, Status.INFEASIBLE);
|
||||
}
|
||||
else {
|
||||
|
||||
// The destination has been found, notify the observers.
|
||||
notifyDestinationReached(dest);
|
||||
|
||||
// Create the path from the array of predecessors...
|
||||
ArrayList<Arc> arcs = new ArrayList<>();
|
||||
Arc arc = labels[dest.getId()].getPere();
|
||||
|
||||
while (arc != null) {
|
||||
arcs.add(arc);
|
||||
|
||||
//Pour le test SOMME(couts) = Cout(Label(Destination))
|
||||
SommeCouts += data.getCost(arc);
|
||||
arc = labels[arc.getOrigin().getId()].getPere();
|
||||
}
|
||||
|
||||
// Reverse the path...
|
||||
Collections.reverse(arcs);
|
||||
|
||||
// Create the final solution.
|
||||
solution = new ShortestPathSolution(data, Status.OPTIMAL, new Path(graph, arcs));
|
||||
}
|
||||
|
||||
if (solution.getStatus() != Status.INFEASIBLE) {
|
||||
// Test si le path est valide
|
||||
if (!solution.getPath().isValid()) {
|
||||
System.out.println("Erreur : PATH SOLUTION INVALID !");
|
||||
}
|
||||
|
||||
// Test s'il correspond a Shortest et Fastest de la classe Path
|
||||
// INUTILE, SUJET MAL COMPRIS
|
||||
/*if (data.getMode() == Mode.LENGTH) {
|
||||
if (solution.getPath().getLength() != Path.createShortestPathFromNodes(graph, solution.getPath().getNodes()).getLength()) {
|
||||
System.out.println("Erreur : PATH SOLUTION NOT SHORTEST !");
|
||||
} else {
|
||||
System.out.println("PATH SOLUTION SHORTEST !");
|
||||
}
|
||||
} else {
|
||||
if (solution.getPath().getMinimumTravelTime() != Path.createFastestPathFromNodes(graph, solution.getPath().getNodes()).getMinimumTravelTime()) {
|
||||
System.out.println("Erreur : PATH SOLUTION NOT FASTEST !");
|
||||
} else {
|
||||
System.out.println("PATH SOLUTION FASTEST !");
|
||||
}
|
||||
}*/
|
||||
|
||||
if ((int)(SommeCouts * 1000) != (int)(labels[dest.getId()].getCost() * 1000)) {
|
||||
System.out.println("Erreur : Cost label Dest (" + labels[dest.getId()].getCost() + ") != Somme(cost) (" + SommeCouts + ")");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return solution;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,14 @@ public class Label implements Comparable<Label>{
|
|||
return this.cout;
|
||||
}
|
||||
|
||||
public double getEstimation() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double getTotalCost() {
|
||||
return this.cout;
|
||||
}
|
||||
|
||||
public Arc getPere() {
|
||||
return this.pere;
|
||||
}
|
||||
|
@ -43,7 +51,13 @@ public class Label implements Comparable<Label>{
|
|||
}
|
||||
|
||||
public int compareTo(Label o) {
|
||||
double diff = this.cout - o.cout;
|
||||
double diff = this.getTotalCost() - o.getTotalCost();
|
||||
if (diff < 0.0) {
|
||||
return -1;
|
||||
} else if (diff > 0.0) {
|
||||
return 1;
|
||||
} else {
|
||||
diff = this.getEstimation() - o.getEstimation();
|
||||
if (diff < 0.0) {
|
||||
return -1;
|
||||
} else if (diff > 0.0) {
|
||||
|
@ -53,3 +67,4 @@ public class Label implements Comparable<Label>{
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package org.insa.graphs.algorithm.shortestpath;
|
||||
|
||||
import org.insa.graphs.model.Node;
|
||||
import java.lang.Comparable;
|
||||
|
||||
public class LabelStar extends Label implements Comparable<Label>{
|
||||
|
||||
private double estimation;
|
||||
|
||||
public LabelStar(Node init_Node, double init_estimation) {
|
||||
super(init_Node);
|
||||
this.estimation = init_estimation;
|
||||
}
|
||||
|
||||
public double getEstimation() {
|
||||
return this.estimation;
|
||||
}
|
||||
|
||||
public double getTotalCost() {
|
||||
return this.estimation + this.getCost();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue