Dijkstra fini + petit changement dans label (int en double pour le cout)
This commit is contained in:
parent
8a969440c8
commit
58317db92a
2 changed files with 70 additions and 38 deletions
|
@ -1,10 +1,14 @@
|
||||||
package org.insa.graphs.algorithm.shortestpath;
|
package org.insa.graphs.algorithm.shortestpath;
|
||||||
|
|
||||||
import org.insa.graphs.algorithm.AbstractInputData;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.insa.graphs.algorithm.AbstractSolution;
|
||||||
import org.insa.graphs.algorithm.utils.BinaryHeap;
|
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.Graph;
|
import org.insa.graphs.model.Graph;
|
||||||
import org.insa.graphs.model.Node;
|
import org.insa.graphs.model.Node;
|
||||||
import org.insa.graphs.model.Arc;
|
|
||||||
import org.insa.graphs.model.Path;
|
import org.insa.graphs.model.Path;
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,53 +46,81 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
||||||
// on indique à chaque label le sommet courant dont il s'occupe
|
// on indique à chaque label le sommet courant dont il s'occupe
|
||||||
// le constructeur utilisé indique directement qu'on ne connait pas l'arc pere, que le sommet
|
// le constructeur utilisé indique directement qu'on ne connait pas l'arc pere, que le sommet
|
||||||
// n'est pas marqué et que le cout_courant est infini
|
// n'est pas marqué et que le cout_courant est infini
|
||||||
tableau_label[nodes.getId()]= new Label(nodes);
|
tableau_label[nodes.getId()]= new Label(nodes);
|
||||||
}
|
}
|
||||||
// on met un coût nul pour le sommet origine
|
// on met un coût nul pour le sommet origine
|
||||||
tableau_label[origin.getId()].setcoutrealise(0);
|
tableau_label[origin.getId()].setcoutrealise(0);
|
||||||
// on met le label du sommet origine dans le tas
|
// on met le label du sommet origine dans le tas
|
||||||
// il n'est pas nécessaire de réordonner le tas car cela est implémenté dans la méthode insert
|
// il n'est pas nécessaire de réordonner le tas car cela est implémenté dans la méthode insert
|
||||||
tas.insert(tableau_label[origin.getId()]);
|
tas.insert(tableau_label[origin.getId()]);
|
||||||
|
// variable qui nous permet de garder les arcs ajoutés pour les mettre dans le path plus tard
|
||||||
|
List<Arc> arcsajout = new ArrayList<Arc>();
|
||||||
// itération
|
// itération
|
||||||
// condition d'arrêt 1: tas vide (soit on a réellement fini soit le point de destination ne fait pas parti de la même composante connexe)
|
// condition d'arrêt 1: tas vide (soit on a réellement fini soit le point de destination ne fait pas parti de la même composante connexe)
|
||||||
// condition d'arrêt 2: pour gagner du temps s'arrêter quand le sommet destination a été trouvé
|
// condition d'arrêt 2: pour gagner du temps s'arrêter quand le sommet destination a été trouvé
|
||||||
while ((!tas.isEmpty()) && (tableau_label[destination.getId()].getmarque()==false)){
|
while ((!tas.isEmpty()) && (tableau_label[destination.getId()].getmarque()==false)){
|
||||||
// on extrait le label avec le coût le plus faible et on le supprime du tas
|
// on extrait le label avec le coût le plus faible et on le supprime du tas
|
||||||
tas.findMin().setmarque(true);
|
// inutile : tas.findMin().setmarque(true);
|
||||||
labelcourant = tas.deleteMin();
|
labelcourant = tas.deleteMin();
|
||||||
// marque le sommet du label qu'on vient de récupérer
|
labelcourant.setmarque(true);
|
||||||
/* for (int i=0;i<nbNodes;i++){
|
|
||||||
if (labelcourant == tableau_label[i]){
|
|
||||||
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
// pour tous les successeurs du sommet qui a ce label on regarde le coût
|
|
||||||
// pour l'instant on n'essaye pas de gagner du temps sur la boucle for mais il serait
|
|
||||||
//intéressant de ne regarder que les labels non marqué
|
|
||||||
// pour l'ensemble des noeuds que j'ai
|
|
||||||
for (Node nodes : graph.getNodes()){
|
|
||||||
// pour l'ensemble des arts existants à partir du nodecourant
|
// pour l'ensemble des arts existants à partir du nodecourant
|
||||||
for (Arc arcscourants : labelcourant.getsommetcourant().getSuccessors()){
|
for (Arc arcscourants : labelcourant.getsommetcourant().getSuccessors()){
|
||||||
// si l'arc qu'on a est lié au noeud étudié alors on vérifie son coût
|
Node successeur = arcscourants.getDestination();
|
||||||
//if ()
|
// si le successeur n'est pas marqué on vérifie son coût courant
|
||||||
|
if(!(tableau_label[successeur.getId()].getmarque())) {
|
||||||
|
// on accède au cout de l'arc (partie inspirée de BellmanFord)
|
||||||
|
double cout_arc = data.getCost(arcscourants);
|
||||||
|
// on accède au coût du sommet à partir de son label
|
||||||
|
double cout_actuel = tableau_label[successeur.getId()].getCost();
|
||||||
|
// on calcul son nouveau coût en additionnant le coût de son sommet prédeccesseur et le coût de l'arc qui les relie
|
||||||
|
double cout_nv = labelcourant.getCost() + cout_arc;
|
||||||
|
// on compare les deux coûts
|
||||||
|
if(cout_nv<cout_actuel) {
|
||||||
|
Label labelchanger = tableau_label [successeur.getId()];
|
||||||
|
// si le coût nv est meilleur on update le cout du sommet au sein du label
|
||||||
|
labelchanger.setcoutrealise(cout_nv);
|
||||||
|
// on indique que l'arc pere est arcscourants
|
||||||
|
labelchanger.setarcperefils(arcscourants);
|
||||||
|
try {
|
||||||
|
// on met ce noeud dans le tas si il n'y a jamais été mis auparavant
|
||||||
|
tas.remove(labelchanger);
|
||||||
|
tas.insert(labelchanger);
|
||||||
|
} catch (ElementNotFoundException e) {
|
||||||
|
// on update sa place dans le tas s'il y est déjà
|
||||||
|
tas.insert(labelchanger);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/*// Retrieve weight of the arc.
|
|
||||||
double w = data.getCost(arc);
|
|
||||||
double oldDistance = distances[arc.getDestination().getId()];
|
|
||||||
double newDistance = distances[node.getId()] + w
|
|
||||||
|
|
||||||
// On met la valeur du label de l'origine à 0
|
if(tableau_label[destination.getId()].getmarque()==false) {
|
||||||
// when the algorithm terminates, return the solution that has been found
|
solution = new ShortestPathSolution(data, AbstractSolution.Status.INFEASIBLE);
|
||||||
*/
|
}
|
||||||
|
else {
|
||||||
return solution;
|
// stockage de la liste des arcs de l'origine a la destination (on a besoin de le faire dans l'ordre inverse)
|
||||||
|
Arc dernier_arc_traite = tableau_label[destination.getId()].getarcpere_fils();
|
||||||
|
// avec la condition du while on s'arrete à l'origine
|
||||||
|
while (dernier_arc_traite !=null) {
|
||||||
|
// ajouter en debut de liste pour avoir le bon path a la fin
|
||||||
|
arcsajout.add(0,dernier_arc_traite);
|
||||||
|
// passer à l'arc précédent
|
||||||
|
dernier_arc_traite = tableau_label[dernier_arc_traite.getOrigin().getId()].getarcpere_fils();
|
||||||
|
}
|
||||||
|
// construction du path
|
||||||
|
Path path_possible= new Path(graph,arcsajout);
|
||||||
|
solution = new ShortestPathSolution(data,AbstractSolution.Status.OPTIMAL,path_possible);
|
||||||
|
}
|
||||||
|
// when the algorithm terminates, return the solution that has been found
|
||||||
|
return solution;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ public class Label implements Comparable<Label>{
|
||||||
// vrai lorsque le coût min du sommet est connu par l'algorithme
|
// vrai lorsque le coût min du sommet est connu par l'algorithme
|
||||||
private boolean marque;
|
private boolean marque;
|
||||||
// valeur courant du plus court chemin depuis l'origine vers le sommet
|
// valeur courant du plus court chemin depuis l'origine vers le sommet
|
||||||
private int cout_realise;
|
private double cout_realise;
|
||||||
// sommet père du sommet que l'on traite (dans le plus court chemin courant)
|
// sommet père du sommet que l'on traite (dans le plus court chemin courant)
|
||||||
// pas besoin car on peut l'avoir avec getOrigin sur arcperefils ( Node pere;)
|
// pas besoin car on peut l'avoir avec getOrigin sur arcperefils ( Node pere;)
|
||||||
// arc correspondant au chemin (le plus court car on peut avoir plusieurs arcs) du père vers le sommet courant
|
// arc correspondant au chemin (le plus court car on peut avoir plusieurs arcs) du père vers le sommet courant
|
||||||
|
@ -33,7 +33,7 @@ public class Label implements Comparable<Label>{
|
||||||
}
|
}
|
||||||
|
|
||||||
//setter cout_realise
|
//setter cout_realise
|
||||||
public void setcoutrealise(int cout_realise) {
|
public void setcoutrealise(double cout_realise) {
|
||||||
this.cout_realise = cout_realise;
|
this.cout_realise = cout_realise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,18 +53,18 @@ public class Label implements Comparable<Label>{
|
||||||
}
|
}
|
||||||
|
|
||||||
//getter cout_realise (a verifier si c'est la meme chose que cout_realisé)
|
//getter cout_realise (a verifier si c'est la meme chose que cout_realisé)
|
||||||
public int getCost() {
|
public double getCost() {
|
||||||
return this.cout_realise;
|
return this.cout_realise;
|
||||||
}
|
}
|
||||||
|
|
||||||
//getter arcpere_fils
|
//getter arcpere_fils
|
||||||
public Arc arcpere_fils() {
|
public Arc getarcpere_fils() {
|
||||||
return this.arcpere_fils;
|
return this.arcpere_fils;
|
||||||
}
|
}
|
||||||
// on override la méthode de comparaison
|
// on override la méthode de comparaison
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(Label other){
|
public int compareTo(Label other){
|
||||||
return Integer.compare(this.getCost(),other.getCost());
|
return Double.compare(this.getCost(),other.getCost());
|
||||||
}
|
}
|
||||||
// ces labels sont associé à chaque noeud : les noeuds du graphes sont numérotés de 0 à N-1
|
// ces labels sont associé à chaque noeud : les noeuds du graphes sont numérotés de 0 à N-1
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue