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;
|
||||
|
||||
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.ElementNotFoundException;
|
||||
import org.insa.graphs.model.Arc;
|
||||
import org.insa.graphs.model.Graph;
|
||||
import org.insa.graphs.model.Node;
|
||||
import org.insa.graphs.model.Arc;
|
||||
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
|
||||
// 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
|
||||
tableau_label[nodes.getId()]= new Label(nodes);
|
||||
tableau_label[nodes.getId()]= new Label(nodes);
|
||||
}
|
||||
// on met un coût nul pour le sommet origine
|
||||
tableau_label[origin.getId()].setcoutrealise(0);
|
||||
// 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
|
||||
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
|
||||
// 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é
|
||||
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
|
||||
tas.findMin().setmarque(true);
|
||||
// inutile : tas.findMin().setmarque(true);
|
||||
labelcourant = tas.deleteMin();
|
||||
// marque le sommet du label qu'on vient de récupérer
|
||||
/* for (int i=0;i<nbNodes;i++){
|
||||
if (labelcourant == tableau_label[i]){
|
||||
labelcourant.setmarque(true);
|
||||
|
||||
}
|
||||
}*/
|
||||
// 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
|
||||
for (Arc arcscourants : labelcourant.getsommetcourant().getSuccessors()){
|
||||
// si l'arc qu'on a est lié au noeud étudié alors on vérifie son coût
|
||||
//if ()
|
||||
Node successeur = arcscourants.getDestination();
|
||||
// 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
|
||||
// when the algorithm terminates, return the solution that has been found
|
||||
*/
|
||||
|
||||
return solution;
|
||||
if(tableau_label[destination.getId()].getmarque()==false) {
|
||||
solution = new ShortestPathSolution(data, AbstractSolution.Status.INFEASIBLE);
|
||||
}
|
||||
else {
|
||||
// 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
|
||||
private boolean marque;
|
||||
// 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)
|
||||
// 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
|
||||
|
@ -33,7 +33,7 @@ public class Label implements Comparable<Label>{
|
|||
}
|
||||
|
||||
//setter cout_realise
|
||||
public void setcoutrealise(int cout_realise) {
|
||||
public void setcoutrealise(double 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é)
|
||||
public int getCost() {
|
||||
public double getCost() {
|
||||
return this.cout_realise;
|
||||
}
|
||||
|
||||
//getter arcpere_fils
|
||||
public Arc arcpere_fils() {
|
||||
public Arc getarcpere_fils() {
|
||||
return this.arcpere_fils;
|
||||
}
|
||||
// on override la méthode de comparaison
|
||||
@Override
|
||||
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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue