Dijkstra fini + petit changement dans label (int en double pour le cout)

This commit is contained in:
knzrd 2025-05-22 19:30:23 +02:00
parent 8a969440c8
commit 58317db92a
2 changed files with 70 additions and 38 deletions

View file

@ -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);
}
}
}
}
}
} 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;
}
}
/*// 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;
}
} }

View file

@ -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
} }