ajout: Implémentation de l'algorithme de Dijkstra
This commit is contained in:
parent
195b069490
commit
369b12ee76
4 changed files with 139 additions and 10 deletions
|
|
@ -1,5 +1,17 @@
|
|||
package org.insa.graphs.algorithm.shortestpath;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.insa.graphs.algorithm.AbstractSolution.Status;
|
||||
import org.insa.graphs.algorithm.utils.BinaryHeap;
|
||||
import org.insa.graphs.algorithm.utils.ElementNotFoundException;
|
||||
import org.insa.graphs.model.Arc;
|
||||
import org.insa.graphs.model.Node;
|
||||
import org.insa.graphs.model.Path;
|
||||
|
||||
|
||||
public class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
||||
|
||||
public DijkstraAlgorithm(ShortestPathData data) {
|
||||
|
|
@ -8,17 +20,84 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
|||
|
||||
@Override
|
||||
protected ShortestPathSolution doRun() {
|
||||
|
||||
// retrieve data from the input problem (getInputData() is inherited from the
|
||||
// parent class ShortestPathAlgorithm)
|
||||
final ShortestPathData data = getInputData();
|
||||
|
||||
// variable that will contain the solution of the shortest path problem
|
||||
|
||||
System.out.println("==> Initialisation du tas binaire");
|
||||
final HashMap<Integer, Label> labels = new HashMap<>(); // clé-valeur pour retrouver le label associé à un noeud à partir de son id
|
||||
final BinaryHeap<Label> heap = new BinaryHeap<>(); // tas binaire pour retrouver le min en temps constant
|
||||
final Label label = new Label(data.getOrigin(), null, 0.0, false);
|
||||
heap.insert(label);
|
||||
labels.put(data.getOrigin().getId(), label);
|
||||
System.out.println("==> Tas initialisté");
|
||||
//System.out.println(heap.toStringTree());
|
||||
|
||||
System.out.println("==> Dijkstra commence");
|
||||
notifyOriginProcessed(data.getOrigin());
|
||||
Label currentLabel = null;
|
||||
boolean destinationReached = false;
|
||||
while (!destinationReached && !heap.isEmpty() && (currentLabel=heap.deleteMin()) != null) {
|
||||
if (currentLabel.getCoutRealise() == Double.MAX_VALUE)
|
||||
break;
|
||||
|
||||
currentLabel.setMarque(true);
|
||||
notifyNodeMarked(currentLabel.getNode());
|
||||
|
||||
// Si on atteint notre destination, on arrête l'algo
|
||||
if (currentLabel.getNode().equals(data.getDestination())) {
|
||||
destinationReached = true;
|
||||
} else {
|
||||
for (Arc arc : currentLabel.getNode().getSuccessors()) {
|
||||
if (data.isAllowed(arc)) {
|
||||
Label successorLabel = labels.get(arc.getDestination().getId());
|
||||
if (successorLabel == null) successorLabel = new Label(arc.getDestination());
|
||||
if (successorLabel.getCoutRealise() > currentLabel.getCoutRealise() + data.getCost(arc)) {
|
||||
try {
|
||||
heap.remove(successorLabel);
|
||||
} catch(ElementNotFoundException e) {
|
||||
// BinaryHeap#remove a échoué, donc ça veut dire qu'on doit juste insérer, pas mettre à jour, mais ça ne change rien au niveau du code
|
||||
}
|
||||
|
||||
|
||||
successorLabel.setCoutRealise(currentLabel.getCoutRealise() + data.getCost(arc));
|
||||
successorLabel.setArc(arc);
|
||||
heap.insert(successorLabel);
|
||||
labels.put(arc.getDestination().getId(), successorLabel);
|
||||
|
||||
notifyNodeReached(arc.getDestination());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ShortestPathSolution solution = null;
|
||||
if (destinationReached) {
|
||||
notifyDestinationReached(data.getDestination());
|
||||
System.out.println("==> Dijkstra termine et a trouvé");
|
||||
|
||||
// TODO: implement the Dijkstra algorithm
|
||||
// On part de la fin, et on remonte petit à petit vers le sommet d'origine
|
||||
System.out.println("==> On recompose le chemin");
|
||||
|
||||
List<Arc> arcs = new ArrayList<>();Node currentNode = data.getDestination();
|
||||
while(currentNode != data.getOrigin()) {
|
||||
final Arc arc = labels.get(currentNode.getId()).getArc();
|
||||
if (arc != null) {
|
||||
arcs.add(arc);
|
||||
currentNode = arc.getOrigin();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
System.out.println("==> Fini");
|
||||
|
||||
Path path = new Path(data.getGraph(), arcs.reversed());
|
||||
solution = new ShortestPathSolution(data, Status.OPTIMAL, path);
|
||||
} else {
|
||||
System.out.println("==> Dijkstra termine mais n'a pas trouvé");
|
||||
solution = new ShortestPathSolution(data, Status.INFEASIBLE);
|
||||
}
|
||||
|
||||
// when the algorithm terminates, return the solution that has been found
|
||||
return solution;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
package org.insa.graphs.algorithm.shortestpath;
|
||||
|
||||
import org.insa.graphs.model.Arc;
|
||||
import org.insa.graphs.model.Node;
|
||||
import java.lang.Comparable;
|
||||
|
||||
public class Label implements Comparable<Label> {
|
||||
private Node node;
|
||||
private Arc arc;
|
||||
private Double coutRealise;
|
||||
private boolean marque;
|
||||
|
||||
public Label(Node node) {
|
||||
this.node = node;
|
||||
this.arc = null;
|
||||
this.coutRealise = Double.MAX_VALUE;
|
||||
this.marque = false;
|
||||
}
|
||||
public Label(Node node, Arc arc, Double coutRealise, boolean marque){
|
||||
this.node = node;
|
||||
this.arc = arc;
|
||||
this.coutRealise = coutRealise;
|
||||
this.marque = marque;
|
||||
}
|
||||
|
||||
public Double getCoutRealise() { return this.coutRealise; }
|
||||
public Node getNode() { return this.node; }
|
||||
public Arc getArc() { return this.arc; }
|
||||
public boolean getMarque() { return this.marque; }
|
||||
|
||||
public void setCoutRealise(Double cout) { this.coutRealise = cout; }
|
||||
public void setArc(Arc arc) { this.arc = arc; }
|
||||
public void setMarque(boolean marque) { this.marque = marque; }
|
||||
|
||||
//public Double getCost() {
|
||||
// return this.coutRealise;
|
||||
//}
|
||||
|
||||
@Override
|
||||
public int compareTo(Label l) {
|
||||
// si deux nodes ont le même coût, on prend celui à l'id le plus petit
|
||||
if (this.getCoutRealise().compareTo(l.getCoutRealise()) == 0)
|
||||
return ((Integer) this.getNode().getId()).compareTo((Integer) l.getNode().getId());
|
||||
else
|
||||
return this.getCoutRealise().compareTo(l.getCoutRealise());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Label(Node=" + this.node.getId() + "; Coût=" + this.coutRealise + "; Marque=" + (this.marque ? "OUI" : "NON") + ") [" + this.hashCode() + "]";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
package org.insa.graphs.algorithm.utils;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Queue;
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -64,8 +64,8 @@ public class Launch {
|
|||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// Pour mapName: un fichier .mapgr pour un graphe simple, un fichier .mapfg pour une carte (le .mapgr associé doit être présent dans le même dossier)
|
||||
final String mapName = "C:\\Users\\Brendan\\Mon Drive\\INSA\\3MIC\\S6 - Graphes\\BE-Graphes\\Maps\\insa.mapfg";
|
||||
final String pathName = "C:\\Users\\Brendan\\Mon Drive\\INSA\\3MIC\\S6 - Graphes\\BE-Graphes\\Paths\\path_fr31insa_rangueil_r2.path";
|
||||
final String mapName = "/mnt/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Maps/midi-pyrenees.mapgr";
|
||||
final String pathName = "/mnt/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Paths/path_fr31insa_rangueil_r2.path";
|
||||
|
||||
final Graph graph;
|
||||
final Path path;
|
||||
|
|
|
|||
Loading…
Reference in a new issue