finalisation de Dijksra avec question bonus pour les piétons
This commit is contained in:
förälder
2d42cfe956
incheckning
adad22dca4
3 ändrade filer med 115 tillägg och 146 borttagningar
|
|
@ -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()] =
|
||||||
dans graphe y'a la liste de nodes
|
new Label(node, false, Double.POSITIVE_INFINITY, null);
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
// Origine : coût 0, non marqué, pas de père
|
||||||
|
labels[data.getOrigin().getId()].setCoutRealise(0);
|
||||||
|
|
||||||
|
BinaryHeap<Label> heap = new BinaryHeap<>();
|
||||||
|
heap.insert(labels[data.getOrigin().getId()]);
|
||||||
|
|
||||||
for(Arc arcActuel : listeSuccesseurs){
|
notifyOriginProcessed(data.getOrigin());
|
||||||
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);*/
|
|
||||||
|
|
||||||
leTas.insert(labelAInserer); //pour la comparaison la class BinaryHeap utilise la fct compareTo qu'on a redéfinit dans Label
|
while (!heap.isEmpty()) {
|
||||||
}
|
Label LabelActuel = heap.deleteMin();
|
||||||
int indexLabel=0;
|
Node NodeActuel = LabelActuel.getSommetCourant();
|
||||||
int indexSolution=-1;
|
|
||||||
|
|
||||||
ArrayList<Node> listeSommetsTraites=new List<Node>;
|
// sommet traité
|
||||||
|
LabelActuel.setMarque(true);
|
||||||
|
|
||||||
while (!leTas.isEmpty()){
|
// On a atteint la destination on s'arrête
|
||||||
Label labelMin = leTas.findMin();
|
if (NodeActuel.equals(data.getDestination())) {
|
||||||
listeFinal.add(indexLabel,labelMin);
|
notifyDestinationReached(NodeActuel);
|
||||||
listeSommetsTraites.add(indexLabel,labelMin.getSommetCourant());
|
break;
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
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é
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
private Node sommetCourant;
|
* fin de l'algorithme, mieux vaut stocker l'arc plutôt que seulement le père.
|
||||||
private Boolean marque;
|
* Ajoutez les getters. Important pour la suite : une méthode getCost() qui renvoie
|
||||||
private double coutRealise;
|
* le coût de ce label. Pour le moment, le coût est égal au coût réalisé.
|
||||||
private Arc pere;
|
*/
|
||||||
public Label(Node sommetCourant,Boolean marque,double coutRealise, Arc pere){
|
private Node sommetCourant;
|
||||||
this.sommetCourant=sommetCourant;
|
private Boolean marque;
|
||||||
this.marque=marque;
|
private double coutRealise;
|
||||||
this.coutRealise=coutRealise;
|
private Arc pere;
|
||||||
this.pere=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() {
|
public Node getSommetCourant() {
|
||||||
|
|
@ -35,42 +40,43 @@ 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){
|
|
||||||
int retour;
|
|
||||||
if (coutRealise==L.getCoutRealise()){
|
|
||||||
retour=0;
|
|
||||||
}else {
|
|
||||||
retour=(int)(coutRealise-L.getCoutRealise());
|
|
||||||
}
|
}
|
||||||
return retour;
|
|
||||||
|
|
||||||
}
|
public Arc getPere() {
|
||||||
|
return pere;
|
||||||
|
}
|
||||||
|
|
||||||
public void setSommetCourant(Node sommetCourant) {
|
// renvoit 0 si égal sinon renvoit la différence.
|
||||||
this.sommetCourant = sommetCourant;
|
@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) {
|
public void setSommetCourant(Node sommetCourant) {
|
||||||
this.coutRealise = coutRealise;
|
this.sommetCourant = sommetCourant;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPere(Arc pere) {
|
public void setMarque(Boolean marque) {
|
||||||
this.pere = pere;
|
this.marque = marque;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setCoutRealise(double coutRealise) {
|
||||||
public int compareTo(Object arg0) {
|
this.coutRealise = coutRealise;
|
||||||
// TODO Auto-generated method stub
|
}
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'compareTo'");
|
|
||||||
}
|
public void setPere(Arc pere) {
|
||||||
|
this.pere = pere;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Laddar…
Referens i nytt ärende