modif dijkstra + méthode de maj du binaryHeap

This commit is contained in:
Cavailles Kevin 2020-04-24 21:19:30 +02:00
parent 5ef3259735
commit 5c9a41dd1d
3 changed files with 125 additions and 96 deletions

View file

@ -27,104 +27,112 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
final int nbNodes = graph.size(); final int nbNodes = graph.size();
// Create the heap and a static array to store the labels // Create the heap and a static array to store the labels
org.insa.graphs.algorithm.utils.BinaryHeap<Label> labelsHeap = new BinaryHeap<>(); BinaryHeap<Label> tas = new BinaryHeap<Label>();
Label labelsList[] = new Label[nbNodes]; Label labels[] = new Label[graph.getNodes().size()];
Arrays.fill(labelsList, null); Arrays.fill(labels, null);
//Put the origin in the heap and in the list Label origine = new Label(data.getOrigin(), 0 , null);
Node origin = data.getOrigin(); labels[data.getOrigin().getId()] = origine;
labelsList[origin.getId()] = new Label(origin, 0, null); tas.insert(origine);
labelsHeap.insert(labelsList[origin.getId()]);
Label minimum, successeur;
// Notify observers about the first event (origin processed).
notifyOriginProcessed(data.getOrigin()); int cptErreurs = 0;
// Initialize array of predecessors. //Tant que le tas n'est pas vide et que la destination n'est pas atteinte ou n'est pas marquée
Arc[] predecessorArcs = new Arc[nbNodes]; while(!tas.isEmpty() &&
(labels[data.getDestination().getId()] == null || !labels[data.getDestination().getId()].isMarked() ) )
Label current, next; {
// While the heap has elements and the destination has not been reached and marked
while (!labelsHeap.isEmpty()
&& (labelsList[data.getDestination().getId()] == null || !labelsList[data.getDestination().getId()].isMarked() )) {
// if(!labelsHeap.isValid()) { if(!tas.isValid()) {
// System.out.println("arbre non valide"); cptErreurs++;
// } }
// Remove the min //Récupère le minimum (= racine)
current = labelsHeap.findMin(); minimum = tas.findMin();
//System.out.println("cout :"+current.getCost());
if(minimum.getCurrent() == data.getOrigin()) {
notifyOriginProcessed(data.getOrigin());
}
if(minimum.getCurrent() == data.getDestination()) {
notifyDestinationReached(data.getDestination());
}
//Supprime le minimum
try { try {
labelsHeap.remove(current); tas.remove(minimum);
} catch (Exception e) { }catch(Exception e) {
System.out.println("fatal error"); System.out.println("fatal error");
} }
current.setMark(); minimum.setMark();
notifyNodeMarked(current.getCurrent()); notifyNodeMarked(minimum.getCurrent());
// Iterate over the arcs of the removed element
for (Arc arc : graph.get(current.getCurrent().getId()).getSuccessors()) {
if (!data.isAllowed(arc)) {
continue;
}
//System.out.println("origine : "+arc.getOrigin().getId()+" destination : "+ arc.getDestination().getId());
next = labelsList[arc.getDestination().getId()];
//If the destination of an arc does not exist in the list or is not marked // System.out.println(minimum.getCurrent().getNumberOfSuccessors());
if ( next != null && next.isMarked()) {
//Pour chaque successeurs du noeud minimum
for(Arc arc : minimum.getCurrent().getSuccessors()) {
if(!data.isAllowed(arc)) {
continue; continue;
} }
// Either create it or check if the associated cost can be reduced
if (next == null) {
next = new Label(arc.getDestination(), current.getCost() + data.getCost(arc), arc);
labelsList[arc.getDestination().getId()] = next;
labelsHeap.insert(next);
}else{ successeur = labels[arc.getDestination().getId()];
if (next.getCost() > current.getCost() + data.getCost(arc)) {
next.setCost(current.getCost() + data.getCost(arc)); //Si le successeur n'existe pas, on le crée
next.setFather(arc); if(successeur == null) {
successeur = new Label(arc.getDestination(), minimum.getCost() + data.getCost(arc), arc);
labels[arc.getDestination().getId()] = successeur;
tas.insert(successeur);
notifyNodeReached(successeur.getCurrent());
//Sinon on regarde si on peut optimiser le coût du successeur
}else {
if(successeur.getCost() > minimum.getCost() + data.getCost(arc)) {
successeur.setCost(minimum.getCost() + data.getCost(arc));
successeur.setFather(arc);
try {
tas.miseAJour(successeur);
}catch(Exception e) {
System.out.println("fatal error");
}
} }
} }
notifyNodeReached(arc.getDestination());
} }
//System.out.println("");
} }
ShortestPathSolution solution = null; ShortestPathSolution solution = null;
//Check if the destination has been reached from the source //Regarde si la destination a été atteinte et marquée
if (labelsList[data.getDestination().getId()] == null) { if(labels[data.getDestination().getId()] != null && labels[data.getDestination().getId()].isMarked()) {
solution = new ShortestPathSolution(data, Status.INFEASIBLE);
} else { //On récupère tous les arcs constituant le chemin
// The destination has been found, notify the observers. //en partant de la destination et en remontant jusqu'à l'origine
notifyDestinationReached(data.getDestination()); ArrayList<Arc> arcsSolution = new ArrayList<>();
Arc arc = labels[data.getDestination().getId()].getFather();
// Create the path from the array of predecessors... while(arc != null) {
ArrayList<Arc> arcs = new ArrayList<>(); arcsSolution.add(arc);
Arc arc = labelsList[data.getDestination().getId()].getFather(); arc = labels[arc.getOrigin().getId()].getFather();
while (arc != null) {
arcs.add(arc);
arc = labelsList[arc.getOrigin().getId()].getFather();
} }
// Reverse the arcs' path... Collections.reverse(arcsSolution);
Collections.reverse(arcs);
solution = new ShortestPathSolution(data, Status.OPTIMAL, new Path(graph, arcsSolution));
// Create the final solution.
solution = new ShortestPathSolution(data, Status.OPTIMAL, new Path(graph, arcs)); //Sinon, il n'y a pas de solution
}else {
solution = new ShortestPathSolution(data, Status.INFEASIBLE);
} }
System.out.println("nb erreurs = "+cptErreurs);
return solution; return solution;
} }

View file

@ -48,12 +48,6 @@ public class Label implements Comparable<Label>{
} }
@Override @Override
public int compareTo(Label o) { public int compareTo(Label o) {
if( (this.getCost()-o.getCost() ) < 0) { return Double.compare(this.getCost(), o.getCost());
return -1;
}else if( (this.getCost()-o.getCost() ) > 0) {
return 1;
}else {
return 0;
}
} }
} }

View file

@ -204,17 +204,44 @@ public class BinaryHeap<E extends Comparable<E>> implements PriorityQueue<E> {
} }
// public boolean isValid() { //Met à jour l'arbre à partir à partir d'un élément dont le coût a changé
// public void miseAJour(E x) throws ElementNotFoundException {
// for(int i=1; i<this.size(); i++) {
// E current = this.array.get(i); if(this.isEmpty() || x == null){
// E parent = this.array.get(this.indexParent(i)); throw new ElementNotFoundException(x);
// if( current.compareTo(parent) < 0) { }
// return false;
// } int index = -1;
// } // Iterate over the array and check if the x exists
// return true; for(int i=0; i<this.currentSize;i++) {
// } if(this.array.get(i).equals(x)) {
index = i;
break;
}
}
if(index == -1) {
throw new ElementNotFoundException(x);
}
this.percolateDown(index);
this.percolateUp(index);
}
public boolean isValid() {
E current;
E parent;
for(int i=1; i<this.currentSize; i++) {
current = this.array.get(i);
parent = this.array.get(this.indexParent(i));
if( current.compareTo(parent) < 0) {
return false;
}
}
return true;
}
/** /**
* Creates a multi-lines string representing a sorted view of this binary heap. * Creates a multi-lines string representing a sorted view of this binary heap.