finalisation de Dijksra avec question bonus pour les piétons

This commit is contained in:
bezza 2025-05-12 18:27:55 +02:00
parent 2d42cfe956
commit adad22dca4
3 changed files with 115 additions and 146 deletions

View file

@ -2,8 +2,6 @@ package org.insa.graphs.algorithm.shortestpath;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.org.insa.graphs.algorithm.shortestpath.Label;
import org.insa.graphs.algorithm.AbstractSolution.Status; import org.insa.graphs.algorithm.AbstractSolution.Status;
import org.insa.graphs.algorithm.utils.BinaryHeap; import org.insa.graphs.algorithm.utils.BinaryHeap;
@ -22,127 +20,92 @@ 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
ShortestPathSolution solution = null; ShortestPathSolution solution = null;
// accès au graphe
Graph graph = data.getGraph();
int nbNodes = graph.size();
// TODO: implement the Dijkstra algorithm // Tableau des labels pour chaque sommet
Label[] labels = new Label[nbNodes];
// Tableau des arcs prédécesseurs pour reconstruire le chemin
Arc[] predecessorArcs = new Arc[nbNodes];
/*pseudo code : // Initialisation des labels
on a à une destination et une origine et un graph pour les appliquer (et arcinspector jsp à quoi sert encore) for (Node node : graph.getNodes()) {
labels[node.getId()] =
new Label(node, false, Double.POSITIVE_INFINITY, null);
}
// Origine : coût 0, non marqué, pas de père
labels[data.getOrigin().getId()].setCoutRealise(0);
dans graphe y'a la liste de nodes BinaryHeap<Label> heap = new BinaryHeap<>();
dans chaque node y'a la liste de succesor avec des arcs heap.insert(labels[data.getOrigin().getId()]);
dans les arcs on peut avoir la destination
dans BinaryHeap on a deletemin qu'on fera à chaque itération de dijkstra pour enlever du tas le sommet avec la plus petite distance de l'origine notifyOriginProcessed(data.getOrigin());
*/ while (!heap.isEmpty()) {
Label LabelActuel = heap.deleteMin();
Node NodeActuel = LabelActuel.getSommetCourant();
Graph graphe = data.getGraph(); // sommet traité
Node nodeOriginel=data.getOrigin(); LabelActuel.setMarque(true);
Node nodeDestination=data.getDestination();
BinaryHeap<Label> leTas=new BinaryHeap<Label>; // On a atteint la destination on s'arrête
if (NodeActuel.equals(data.getDestination())) {
List<Arc> listeSuccesseurs = new List<Arc>; notifyDestinationReached(NodeActuel);
break;
ArrayList<Label> listeFinal=new List<Label>;
//chercher les successeurs de l'origine
if (nodeOriginel.hasSuccessors()){
listeSuccesseurs=nodeOriginel.getSuccessors();
}else {
System.out.println("Le node originel n'a pas de successeurs \n");
} }
// Pour chaque successeur
for (Arc arc : NodeActuel.getSuccessors()) {
if (!data.isAllowed(arc))
continue; // ici c'est pour l'amélioration voiture ou a pied
for(Arc arcActuel : listeSuccesseurs){ Node succ = arc.getDestination();
Label labelAInserer = new Label(arcActuel.getDestination(),true,arcActuel.getMinimumTravelTime(),arcActuel) ; //On set le label à insérer Label succLabel = labels[succ.getId()];
/*labelAInserer.setSommetCourant(arcActuel.getDestination());
labelAInserer.setMarque(true);
labelAInserer.setCoutRealise(arcActuel.getMinimumTravelTime());
labelAInserer.setPere(arcActuel);*/
leTas.insert(labelAInserer); //pour la comparaison la class BinaryHeap utilise la fct compareTo qu'on a redéfinit dans Label if (succLabel.getMarque())
continue; // déjà traité
double newCost = LabelActuel.getCoutRealise() + data.getCost(arc);
if (newCost < succLabel.getCoutRealise()) {
// Mise à jour du coût et du prédécesseur
// Si le sommet a déjà un label dans le tas, on le retire
// avant de le mettre à jour
if (succLabel.getCoutRealise() != Double.POSITIVE_INFINITY) {
heap.remove(succLabel);
} }
int indexLabel=0; succLabel.setCoutRealise(newCost);
int indexSolution=-1; succLabel.setPere(arc);
predecessorArcs[succ.getId()] = arc;
ArrayList<Node> listeSommetsTraites=new List<Node>; // Insertion dans le tas car on est sûr qu'il n'est pas
while (!leTas.isEmpty()){ heap.insert(succLabel);
Label labelMin = leTas.findMin();
listeFinal.add(indexLabel,labelMin);
listeSommetsTraites.add(indexLabel,labelMin.getSommetCourant());
double coutActuel = labelMin.getCoutRealise(); notifyNodeReached(succ);
listeSuccesseurs=labelMin.getSommetCourant().getSuccessors();
for(Arc arcActuel : listeSuccesseurs){
//problème faudrait un if (le sommet a déjà un label dans le tas (vérifier qu'il est dans listeFinal) && le successeur a un cout > coutActuel+arcActuel.getMinimumTravelTime())
//alors on remplace ce label par le nouveau avec un nouveau père, et un nouveau coût minimum
//sinon si (le sommet a déjà un label dans le tas (vérifier qu'il est dans listeFinal))
//ne rien faire
//sinon //alors on a nouveau label et on l'instancie
if (listeSommetsTraites.contains(arcActuel.getOrigin()) && ) //problème => comment identifier ce label ? j'ai juste l'arcActuel
Label labelAInserer = new Label(arcActuel.getDestination(),true,coutActuel+arcActuel.getMinimumTravelTime(),arcActuel) ; //On set le label à insérer
//puis ds tous les cas on insert
leTas.insert(labelAInserer); //pour la comparaison la class BinaryHeap utilise la fct compareTo qu'on a redéfinit dans Label
} }
if(labelMin.getSommetCourant().equals(nodeDestination)){
indexSolution=indexLabel;
} }
indexLabel++;
leTas.deleteMin(); //on enlève l'élément traité
} }
// Construction de la solution
//remplir ShortestPathSolution
//d'abord remplir Path puis ShortestPathData puis status
//////////////////// ATTENTION predecessorArcs à bien faire (vient de l'algo bellmanFord)
// Destination has no predecessor, the solution is infeasible...
if (predecessorArcs[data.getDestination().getId()] == null) { if (predecessorArcs[data.getDestination().getId()] == null) {
solution = new ShortestPathSolution(data, Status.INFEASIBLE); solution = new ShortestPathSolution(data, Status.INFEASIBLE);
} }
else { else {
// Reconstruire le chemin
// The destination has been found, notify the observers.
notifyDestinationReached(data.getDestination());
// Create the path from the array of predecessors...
ArrayList<Arc> arcs = new ArrayList<>(); ArrayList<Arc> arcs = new ArrayList<>();
Arc arc = predecessorArcs[data.getDestination().getId()]; Arc arc = predecessorArcs[data.getDestination().getId()];
while (arc != null) { while (arc != null) {
arcs.add(arc); arcs.add(arc);
arc = predecessorArcs[arc.getOrigin().getId()]; arc = predecessorArcs[arc.getOrigin().getId()];
} }
Collections.reverse(arcs);// on inverse le chemin
// Reverse the path... solution = new ShortestPathSolution(data, Status.OPTIMAL,new Path(graph, arcs));
Collections.reverse(arcs);
// Create the final solution.
solution = new ShortestPathSolution(data, Status.OPTIMAL,
new Path(graphe, arcs));
} }
// when the algorithm terminates, return the solution that has been found
return solution; return solution;
} }

View file

@ -3,24 +3,29 @@ package org.insa.graphs.algorithm.shortestpath;
import org.insa.graphs.model.Arc;// sinon cela compilait pas import org.insa.graphs.model.Arc;// sinon cela compilait pas
import org.insa.graphs.model.Node; import org.insa.graphs.model.Node;
public class Label implements Comparable { public class Label implements Comparable<Label> {
/* sommet courant : sommet associé à ce label (sommet ou numéro de sommet). /*
marque : booléen, vrai lorsque le coût min de ce sommet est définitivement connu par l'algorithme. * sommet courant : sommet associé à ce label (sommet ou numéro de sommet). marque :
coût réalisé : valeur courante du plus court chemin depuis l'origine vers le sommet. Pour éviter toute confusion plus tard, ne l'appelez pas simplement coût. * booléen, vrai lorsque le coût min de ce sommet est définitivement connu par
père : correspond au sommet précédent sur le chemin correspondant au plus court chemin courant. Afin de reconstruire le chemin à la fin de l'algorithme, mieux vaut stocker l'arc plutôt que seulement le père. * l'algorithme. coût réalisé : valeur courante du plus court chemin depuis
Ajoutez les getters. * l'origine vers le sommet. Pour éviter toute confusion plus tard, ne l'appelez pas
Important pour la suite : une méthode getCost() qui renvoie le coût de ce label. Pour le moment, le coût est égal au coût réalisé. * simplement coût. père : correspond au sommet précédent sur le chemin
* correspondant au plus court chemin courant. Afin de reconstruire le chemin à la
* fin de l'algorithme, mieux vaut stocker l'arc plutôt que seulement le père.
* Ajoutez les getters. Important pour la suite : une méthode getCost() qui renvoie
* le coût de ce label. Pour le moment, le coût est égal au coût réalisé.
*/ */
private Node sommetCourant; private Node sommetCourant;
private Boolean marque; private Boolean marque;
private double coutRealise; private double coutRealise;
private Arc pere; private Arc pere;
public Label(Node sommetCourant,Boolean marque,double coutRealise, Arc pere){
this.sommetCourant=sommetCourant; public Label(Node sommetCourant, Boolean marque, double coutRealise, Arc pere) {
this.marque=marque; this.sommetCourant = sommetCourant;
this.coutRealise=coutRealise; this.marque = marque;
this.pere=pere; this.coutRealise = coutRealise;
this.pere = pere;
} }
public Node getSommetCourant() { public Node getSommetCourant() {
@ -35,16 +40,23 @@ private Arc pere;
return coutRealise; return coutRealise;
} }
public double getCost(){ public double getCost() {
return coutRealise; return coutRealise;
} }
//renvoit 0 si égal sinon renvoit la différence.
public int compareTo(Label L){ public Arc getPere() {
return pere;
}
// renvoit 0 si égal sinon renvoit la différence.
@Override
public int compareTo(Label L) {
int retour; int retour;
if (coutRealise==L.getCoutRealise()){ if (coutRealise == L.getCoutRealise()) {
retour=0; retour = 0;
}else { }
retour=(int)(coutRealise-L.getCoutRealise()); else {
retour = (int) (coutRealise - L.getCoutRealise());
} }
return retour; return retour;
@ -66,11 +78,5 @@ private Arc pere;
this.pere = pere; this.pere = pere;
} }
@Override
public int compareTo(Object arg0) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'compareTo'");
}
} }