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;
|
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 class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
||||||
|
|
||||||
public DijkstraAlgorithm(ShortestPathData data) {
|
public DijkstraAlgorithm(ShortestPathData data) {
|
||||||
|
|
@ -8,17 +20,84 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ShortestPathSolution doRun() {
|
protected ShortestPathSolution doRun() {
|
||||||
|
|
||||||
// retrieve data from the input problem (getInputData() is inherited from the
|
|
||||||
// parent class ShortestPathAlgorithm)
|
|
||||||
final ShortestPathData data = getInputData();
|
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;
|
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;
|
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;
|
package org.insa.graphs.algorithm.utils;
|
||||||
|
|
||||||
import java.util.ArrayDeque;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Queue;
|
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -64,8 +64,8 @@ public class Launch {
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
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)
|
// 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 mapName = "/mnt/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Maps/midi-pyrenees.mapgr";
|
||||||
final String pathName = "C:\\Users\\Brendan\\Mon Drive\\INSA\\3MIC\\S6 - Graphes\\BE-Graphes\\Paths\\path_fr31insa_rangueil_r2.path";
|
final String pathName = "/mnt/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Paths/path_fr31insa_rangueil_r2.path";
|
||||||
|
|
||||||
final Graph graph;
|
final Graph graph;
|
||||||
final Path path;
|
final Path path;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue