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.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.utils.BinaryHeap;
@ -22,127 +20,92 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
@Override
protected ShortestPathSolution doRun() {
// retrieve data from the input problem (getInputData() is inherited from the
// parent class ShortestPathAlgorithm)
final ShortestPathData data = getInputData();
// variable that will contain the solution of the shortest path problem
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 :
on a à une destination et une origine et un graph pour les appliquer (et arcinspector jsp à quoi sert encore)
// Initialisation des labels
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
dans chaque node y'a la liste de succesor avec des arcs
dans les arcs on peut avoir la destination
BinaryHeap<Label> heap = new BinaryHeap<>();
heap.insert(labels[data.getOrigin().getId()]);
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();
Node nodeOriginel=data.getOrigin();
Node nodeDestination=data.getDestination();
// sommet traité
LabelActuel.setMarque(true);
BinaryHeap<Label> leTas=new BinaryHeap<Label>;
List<Arc> listeSuccesseurs = new List<Arc>;
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");
// On a atteint la destination on s'arrête
if (NodeActuel.equals(data.getDestination())) {
notifyDestinationReached(NodeActuel);
break;
}
// 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){
Label labelAInserer = new Label(arcActuel.getDestination(),true,arcActuel.getMinimumTravelTime(),arcActuel) ; //On set le label à insérer
/*labelAInserer.setSommetCourant(arcActuel.getDestination());
labelAInserer.setMarque(true);
labelAInserer.setCoutRealise(arcActuel.getMinimumTravelTime());
labelAInserer.setPere(arcActuel);*/
Node succ = arc.getDestination();
Label succLabel = labels[succ.getId()];
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;
int indexSolution=-1;
succLabel.setCoutRealise(newCost);
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()){
Label labelMin = leTas.findMin();
listeFinal.add(indexLabel,labelMin);
listeSommetsTraites.add(indexLabel,labelMin.getSommetCourant());
heap.insert(succLabel);
double coutActuel = labelMin.getCoutRealise();
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
notifyNodeReached(succ);
}
if(labelMin.getSommetCourant().equals(nodeDestination)){
indexSolution=indexLabel;
}
indexLabel++;
leTas.deleteMin(); //on enlève l'élément traité
}
//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...
// Construction de la solution
if (predecessorArcs[data.getDestination().getId()] == null) {
solution = new ShortestPathSolution(data, Status.INFEASIBLE);
}
else {
// The destination has been found, notify the observers.
notifyDestinationReached(data.getDestination());
// Create the path from the array of predecessors...
// Reconstruire le chemin
ArrayList<Arc> arcs = new ArrayList<>();
Arc arc = predecessorArcs[data.getDestination().getId()];
while (arc != null) {
arcs.add(arc);
arc = predecessorArcs[arc.getOrigin().getId()];
}
// Reverse the path...
Collections.reverse(arcs);
// Create the final solution.
solution = new ShortestPathSolution(data, Status.OPTIMAL,
new Path(graphe, arcs));
Collections.reverse(arcs);// on inverse le chemin
solution = new ShortestPathSolution(data, Status.OPTIMAL,new Path(graph, arcs));
}
// when the algorithm terminates, return the solution that has been found
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.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.
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.
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é.
/*
* 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. 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. 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 Boolean marque;
private double coutRealise;
private Arc pere;
public Label(Node sommetCourant,Boolean marque,double coutRealise, Arc pere){
this.sommetCourant=sommetCourant;
this.marque=marque;
this.coutRealise=coutRealise;
this.pere=pere;
private Node sommetCourant;
private Boolean marque;
private double coutRealise;
private Arc pere;
public Label(Node sommetCourant, Boolean marque, double coutRealise, Arc pere) {
this.sommetCourant = sommetCourant;
this.marque = marque;
this.coutRealise = coutRealise;
this.pere = pere;
}
public Node getSommetCourant() {
@ -35,16 +40,23 @@ private Arc pere;
return coutRealise;
}
public double getCost(){
public double getCost() {
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;
if (coutRealise==L.getCoutRealise()){
retour=0;
}else {
retour=(int)(coutRealise-L.getCoutRealise());
if (coutRealise == L.getCoutRealise()) {
retour = 0;
}
else {
retour = (int) (coutRealise - L.getCoutRealise());
}
return retour;
@ -66,11 +78,5 @@ private Arc pere;
this.pere = pere;
}
@Override
public int compareTo(Object arg0) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'compareTo'");
}
}