A*
This commit is contained in:
parent
b59cf7532b
commit
0385a19396
4 changed files with 130 additions and 12 deletions
|
@ -1,9 +1,131 @@
|
||||||
package org.insa.graphs.algorithm.shortestpath;
|
package org.insa.graphs.algorithm.shortestpath;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import javax.print.attribute.standard.Destination;
|
||||||
|
|
||||||
|
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 class AStarAlgorithm extends DijkstraAlgorithm {
|
||||||
|
|
||||||
public AStarAlgorithm(ShortestPathData data) {
|
public AStarAlgorithm(ShortestPathData data) {
|
||||||
super(data);
|
super(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ShortestPathSolution doRun() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// retrieve data from the input problem (getInputData() is inherited from the
|
||||||
|
// parent class ShortestPathAlgorithm)
|
||||||
|
final ShortestPathData data = getInputData();
|
||||||
|
|
||||||
|
// the graph
|
||||||
|
Graph graph = data.getGraph();
|
||||||
|
|
||||||
|
// node number
|
||||||
|
final int nbNodes = graph.size();
|
||||||
|
int nodeId = 0;
|
||||||
|
|
||||||
|
// initialize the labelstar list
|
||||||
|
LabelStar[] labels = new LabelStar[nbNodes];
|
||||||
|
for(Node node : graph.getNodes()){
|
||||||
|
nodeId = node.getId();
|
||||||
|
labels[nodeId] = new LabelStar(node, false, Double.POSITIVE_INFINITY, Point.distance(node.getPoint(), data.getDestination().getPoint()));
|
||||||
|
}
|
||||||
|
|
||||||
|
labels[data.getOrigin().getId()].computedCost = 0;
|
||||||
|
// variable that will contain the solution of the shortest path problem
|
||||||
|
ShortestPathSolution solution = null;
|
||||||
|
|
||||||
|
//binary heap for selected lowest cost
|
||||||
|
BinaryHeap<Label> minHeap = new BinaryHeap<>();
|
||||||
|
minHeap.insert(labels[data.getOrigin().getId()]);
|
||||||
|
|
||||||
|
// the index nodes selected for current loop
|
||||||
|
int IdxNewOrigin = data.getOrigin().getId();
|
||||||
|
|
||||||
|
// two variables to update costs
|
||||||
|
|
||||||
|
double NewDist = 0;
|
||||||
|
double EstimatedCost = 0;
|
||||||
|
|
||||||
|
// A*
|
||||||
|
|
||||||
|
while (!minHeap.isEmpty()) {
|
||||||
|
|
||||||
|
IdxNewOrigin = minHeap.deleteMin().currentNode.getId();
|
||||||
|
labels[IdxNewOrigin].mark = true;
|
||||||
|
|
||||||
|
for (Arc arc : labels[IdxNewOrigin].currentNode.getSuccessors()) { // le arrayList de getSucessors, ça ne retourne que des arc forward. donc pas besoin de vérifier si le chemin est empruntable
|
||||||
|
|
||||||
|
// Small test to check allowed roads...
|
||||||
|
if (!data.isAllowed(arc)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!labels[arc.getDestination().getId()].mark){ // verif du marquage
|
||||||
|
|
||||||
|
EstimatedCost = labels[arc.getDestination().getId()].destCost;
|
||||||
|
NewDist = labels[IdxNewOrigin].computedCost + arc.getLength(); // calcul de la nouvelle distance
|
||||||
|
|
||||||
|
if(labels[arc.getDestination().getId()].getTotalCost( ) > NewDist + EstimatedCost){ // si amélioration
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
minHeap.remove(labels[arc.getDestination().getId()]); // on supprime l'ancien noeud du tas si c'est pas déjà fait
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
labels[arc.getDestination().getId()].computedCost = NewDist; // MAJ coût
|
||||||
|
labels[arc.getDestination().getId()].father = arc; // MAJ père
|
||||||
|
|
||||||
|
|
||||||
|
minHeap.insert(labels[arc.getDestination().getId()]); // on réinsère le noeud dans le tas min
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// a ce stade de l'algo, on a le tableau labels qui est rempli et les father qui sont updated. il faut s'en servir pour calculer le shortest path
|
||||||
|
|
||||||
|
// when the algorithm terminates, return the solution that has been found
|
||||||
|
if (labels[data.getDestination().getId()] == null) {
|
||||||
|
solution = new ShortestPathSolution(data, Status.INFEASIBLE); // au cas ou ce n'est apas connexe
|
||||||
|
}
|
||||||
|
|
||||||
|
else{ // création du shortest path en remontant de père en père
|
||||||
|
|
||||||
|
ArrayList<Arc> arcs = new ArrayList<>(); // contient le PCC
|
||||||
|
Arc arc = labels[data.getDestination().getId()].father; // on remonte au noeud suivant par le biais du père
|
||||||
|
while (arc != null) {
|
||||||
|
arcs.add(arc);
|
||||||
|
arc = labels[arc.getOrigin().getId()].father;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// reverse path because started at destination
|
||||||
|
Collections.reverse(arcs);
|
||||||
|
|
||||||
|
// Create the final solution.
|
||||||
|
solution = new ShortestPathSolution(data, Status.OPTIMAL,
|
||||||
|
new Path(graph, arcs));
|
||||||
|
}
|
||||||
|
|
||||||
|
return solution;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,6 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
||||||
labels[nodeId] = new Label(node, false, Double.POSITIVE_INFINITY);
|
labels[nodeId] = new Label(node, false, Double.POSITIVE_INFINITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
labels[data.getOrigin().getId()].computedCost = 0;
|
|
||||||
labels[data.getOrigin().getId()].computedCost = 0;
|
labels[data.getOrigin().getId()].computedCost = 0;
|
||||||
// variable that will contain the solution of the shortest path problem
|
// variable that will contain the solution of the shortest path problem
|
||||||
ShortestPathSolution solution = null;
|
ShortestPathSolution solution = null;
|
||||||
|
|
|
@ -18,9 +18,9 @@ public class Label implements Comparable<Label>{
|
||||||
this.father = null;
|
this.father = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getTotalCost(){
|
public double getTotalCost(){ // Usefull only for LabelStar
|
||||||
|
|
||||||
return 0;
|
return this.computedCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getCost(){
|
public double getCost(){
|
||||||
|
@ -49,7 +49,7 @@ public class Label implements Comparable<Label>{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(Label other){
|
public int compareTo(Label other){
|
||||||
return Double.compare(this.getCost(), other.getCost());
|
return Double.compare(this.getTotalCost(), other.getTotalCost());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -3,20 +3,17 @@ import org.insa.graphs.model.Node;
|
||||||
|
|
||||||
public class LabelStar extends Label{
|
public class LabelStar extends Label{
|
||||||
|
|
||||||
|
public double destCost; // equivaudrait à l'heuristique
|
||||||
|
|
||||||
public LabelStar(Node currentNode, boolean mark, double computedCost){
|
|
||||||
|
public LabelStar(Node currentNode, boolean mark, double computedCost, double destCost){
|
||||||
|
|
||||||
super(currentNode, mark, computedCost);
|
super(currentNode, mark, computedCost);
|
||||||
|
this.destCost = destCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getTotalCost(){
|
public double getTotalCost(){
|
||||||
|
|
||||||
return 0;
|
return this.getCost() + this.destCost;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(Label other){
|
|
||||||
return Double.compare(this.getCost(), other.getCost());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue