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)
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
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
*/
Graph graphe = data.getGraph();
Node nodeOriginel=data.getOrigin();
Node nodeDestination=data.getDestination();
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");
// 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);
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);*/
BinaryHeap<Label> heap = new BinaryHeap<>();
heap.insert(labels[data.getOrigin().getId()]);
leTas.insert(labelAInserer); //pour la comparaison la class BinaryHeap utilise la fct compareTo qu'on a redéfinit dans Label
}
int indexLabel=0;
int indexSolution=-1;
notifyOriginProcessed(data.getOrigin());
ArrayList<Node> listeSommetsTraites=new List<Node>;
while (!heap.isEmpty()) {
Label LabelActuel = heap.deleteMin();
Node NodeActuel = LabelActuel.getSommetCourant();
while (!leTas.isEmpty()){
Label labelMin = leTas.findMin();
listeFinal.add(indexLabel,labelMin);
listeSommetsTraites.add(indexLabel,labelMin.getSommetCourant());
// sommet traité
LabelActuel.setMarque(true);
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
// On a atteint la destination on s'arrête
if (NodeActuel.equals(data.getDestination())) {
notifyDestinationReached(NodeActuel);
break;
}
if(labelMin.getSommetCourant().equals(nodeDestination)){
indexSolution=indexLabel;
// Pour chaque successeur
for (Arc arc : NodeActuel.getSuccessors()) {
if (!data.isAllowed(arc))
continue; // ici c'est pour l'amélioration voiture ou a pied
Node succ = arc.getDestination();
Label succLabel = labels[succ.getId()];
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);
}
succLabel.setCoutRealise(newCost);
succLabel.setPere(arc);
predecessorArcs[succ.getId()] = arc;
// Insertion dans le tas car on est sûr qu'il n'est pas
heap.insert(succLabel);
notifyNodeReached(succ);
}
}
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

@ -1,26 +1,31 @@
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;
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é.
*/
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;
/*
* 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;
}
public Node getSommetCourant() {
@ -35,42 +40,43 @@ private Arc pere;
return coutRealise;
}
public double getCost(){
return coutRealise;
}
//renvoit 0 si égal sinon renvoit la différence.
public int compareTo(Label L){
int retour;
if (coutRealise==L.getCoutRealise()){
retour=0;
}else {
retour=(int)(coutRealise-L.getCoutRealise());
public double getCost() {
return coutRealise;
}
return retour;
}
public Arc getPere() {
return pere;
}
public void setSommetCourant(Node sommetCourant) {
this.sommetCourant = sommetCourant;
}
// 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());
}
return retour;
public void setMarque(Boolean marque) {
this.marque = marque;
}
}
public void setCoutRealise(double coutRealise) {
this.coutRealise = coutRealise;
}
public void setSommetCourant(Node sommetCourant) {
this.sommetCourant = sommetCourant;
}
public void setPere(Arc pere) {
this.pere = pere;
}
public void setMarque(Boolean marque) {
this.marque = marque;
}
public void setCoutRealise(double coutRealise) {
this.coutRealise = coutRealise;
}
public void setPere(Arc pere) {
this.pere = pere;
}
@Override
public int compareTo(Object arg0) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'compareTo'");
}
}

View file

@ -142,7 +142,7 @@ public class BinaryHeap<E extends Comparable<E>> implements PriorityQueue<E> {
}
}
if (ind == -1) {
if (ind == -1) {
throw new ElementNotFoundException(x);
}