123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- package org.insa.graphs.algorithm.shortestpath;
-
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.HashMap;
-
- import org.insa.graphs.algorithm.AbstractSolution.Status;
- import org.insa.graphs.model.Arc;
- import org.insa.graphs.model.Node;
- import org.insa.graphs.model.Path;
-
- import org.insa.graphs.algorithm.utils.*;
-
- public class DijkstraAlgorithm extends ShortestPathAlgorithm {
-
- class Label implements Comparable<Label> {
- Node sommet_courant, pere;
- Boolean marque;
- double cout;
-
- public Label(Node sommet_courant, Node pere, double cout) {
- this.sommet_courant = sommet_courant;
- this.pere = pere;
- this.marque = false;
- this.cout = cout;
- }
-
- public double getCost() {
- return cout;
- }
-
- public void setMark() {
- this.marque = true;
- }
-
- public int compareTo(Label other) {
- return Double.compare(cout, other.cout);
- }
- }
-
- public DijkstraAlgorithm(ShortestPathData data) {
- super(data);
- }
-
- public Label createLabel(Node n){
- return new Label(n, null, Float.MAX_VALUE);
- }
-
- public Label createLabel(Node n, double cout) {
- return new Label(n, null, cout);
- }
-
- @Override
- protected ShortestPathSolution doRun() {
- // Récupération des données du problème
- final ShortestPathData data = getInputData();
-
- // Cas triviaux
- if (data.getOrigin() == data.getDestination())
- return new ShortestPathSolution(data, Status.OPTIMAL, new Path(data.getGraph(), data.getOrigin()));
-
- // Tas des nodes visités, initialisée avec le node d'origine
- BinaryHeap<Label> visite = new BinaryHeap<Label>();
- visite.insert(new Label(data.getOrigin(), null, 0));
-
- notifyOriginProcessed(data.getOrigin());
-
- // Map de correspondance Node - Label initialisée avec des labels par défaut.
- HashMap<Node, Label> map = new HashMap<Node, Label>();
- for (Node n : data.getGraph().getNodes())
- map.put(n, createLabel(n));
-
- /// Varibles de fonctionnement
- // Varible contenant le node le plus intéressant
- Label smallest;
- // Variable contenant le node destination
- Node dest = data.getDestination();
-
- while (true) {
- // Est-ce qu'il reste des nodes à explorer ?
- // Si oui, on récupère le plus intéressant
- // Sinon, il n'y a pas de solution --> on quitte
- try {
- smallest = visite.deleteMin();
- } catch (EmptyPriorityQueueException e) {
- return new ShortestPathSolution(data, Status.INFEASIBLE);
- }
-
- // On marque ce node
- smallest.setMark();
- notifyNodeMarked(smallest.sommet_courant);
-
- // Si on est arrivé, on arrête
- if (smallest.sommet_courant == dest) break;
-
- // Pour chacun des sommets fils, on regarde s'ils proposent des chemins plus intéressants
- for (Arc arc : smallest.sommet_courant.getSuccessors()) {
-
- // On test si le chemin n'est pas permis, on skip
- if (!data.isAllowed(arc)) continue;
-
- Node node = arc.getDestination();
- Label l = map.get(node);
-
- // S'il est déjà marqué, on skip
- if (l.marque) continue;
-
- double n_cout = smallest.getCost() + data.getCost(arc);
-
- //if (l.compareTo(createLabel(node, n_cout)) == 1) {
- if (l.cout > n_cout) {
- visite.tryremove(l);
- l.cout = n_cout;
- l.pere = smallest.sommet_courant;
- l.sommet_courant = node;
- notifyNodeReached(node);
- visite.insert(l);
- }
- }
- }
-
- notifyDestinationReached(smallest.sommet_courant);
-
- // Liste des nodes formant la route entre notre origine et destination
- ArrayList<Node> nodes = new ArrayList<Node>();
- Label last = smallest;
-
- // On remplit la liste en se référant au père à chaque fois
- nodes.add(last.sommet_courant);
- while (true) {
- smallest = map.get(smallest.pere);
- nodes.add(smallest.sommet_courant);
- if (smallest == map.get(data.getOrigin())) break;
- }
-
- // On inverve le sens des nodes
- Collections.reverse(nodes);
-
- // On créé le chemin
- Path p = Path.createShortestPathFromNodes(data.getGraph(), nodes);
-
- /** Vérification des résultats --> Toutes les tests sont ok */
- // Vérification des coûts croisants (l'adjectif, pas la patisserie)
- //for (Node n: nodes) System.out.println(map.get(n).cout);
-
- // Vérification du chemin
- //if (p.isValid()) System.out.println("Chemin valide !");
- //System.out.println("CD: " + last.cout + "; CPCC: " + p.getLength());
-
-
- // On créé on chemin à partir de la liste que l'on donne en solution
- return new ShortestPathSolution(data, Status.OPTIMAL, p);
- }
- }
|