modif dijkstra + méthode de maj du binaryHeap
This commit is contained in:
parent
5ef3259735
commit
5c9a41dd1d
3 changed files with 125 additions and 96 deletions
|
@ -27,104 +27,112 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
|||
final int nbNodes = graph.size();
|
||||
|
||||
// Create the heap and a static array to store the labels
|
||||
org.insa.graphs.algorithm.utils.BinaryHeap<Label> labelsHeap = new BinaryHeap<>();
|
||||
Label labelsList[] = new Label[nbNodes];
|
||||
Arrays.fill(labelsList, null);
|
||||
BinaryHeap<Label> tas = new BinaryHeap<Label>();
|
||||
Label labels[] = new Label[graph.getNodes().size()];
|
||||
Arrays.fill(labels, null);
|
||||
|
||||
//Put the origin in the heap and in the list
|
||||
Node origin = data.getOrigin();
|
||||
labelsList[origin.getId()] = new Label(origin, 0, null);
|
||||
labelsHeap.insert(labelsList[origin.getId()]);
|
||||
Label origine = new Label(data.getOrigin(), 0 , null);
|
||||
labels[data.getOrigin().getId()] = origine;
|
||||
tas.insert(origine);
|
||||
|
||||
// Notify observers about the first event (origin processed).
|
||||
Label minimum, successeur;
|
||||
|
||||
int cptErreurs = 0;
|
||||
|
||||
//Tant que le tas n'est pas vide et que la destination n'est pas atteinte ou n'est pas marquée
|
||||
while(!tas.isEmpty() &&
|
||||
(labels[data.getDestination().getId()] == null || !labels[data.getDestination().getId()].isMarked() ) )
|
||||
{
|
||||
|
||||
if(!tas.isValid()) {
|
||||
cptErreurs++;
|
||||
}
|
||||
|
||||
//Récupère le minimum (= racine)
|
||||
minimum = tas.findMin();
|
||||
|
||||
if(minimum.getCurrent() == data.getOrigin()) {
|
||||
notifyOriginProcessed(data.getOrigin());
|
||||
}
|
||||
|
||||
// Initialize array of predecessors.
|
||||
Arc[] predecessorArcs = new Arc[nbNodes];
|
||||
if(minimum.getCurrent() == data.getDestination()) {
|
||||
notifyDestinationReached(data.getDestination());
|
||||
}
|
||||
|
||||
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()) {
|
||||
// System.out.println("arbre non valide");
|
||||
// }
|
||||
|
||||
// Remove the min
|
||||
current = labelsHeap.findMin();
|
||||
//System.out.println("cout :"+current.getCost());
|
||||
//Supprime le minimum
|
||||
try {
|
||||
labelsHeap.remove(current);
|
||||
} catch (Exception e) {
|
||||
tas.remove(minimum);
|
||||
}catch(Exception e) {
|
||||
System.out.println("fatal error");
|
||||
}
|
||||
|
||||
current.setMark();
|
||||
notifyNodeMarked(current.getCurrent());
|
||||
minimum.setMark();
|
||||
notifyNodeMarked(minimum.getCurrent());
|
||||
|
||||
// Iterate over the arcs of the removed element
|
||||
for (Arc arc : graph.get(current.getCurrent().getId()).getSuccessors()) {
|
||||
if (!data.isAllowed(arc)) {
|
||||
// System.out.println(minimum.getCurrent().getNumberOfSuccessors());
|
||||
|
||||
//Pour chaque successeurs du noeud minimum
|
||||
for(Arc arc : minimum.getCurrent().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
|
||||
if ( next != null && next.isMarked()) {
|
||||
continue;
|
||||
}
|
||||
successeur = labels[arc.getDestination().getId()];
|
||||
|
||||
// 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);
|
||||
//Si le successeur n'existe pas, on le crée
|
||||
if(successeur == null) {
|
||||
successeur = new Label(arc.getDestination(), minimum.getCost() + data.getCost(arc), arc);
|
||||
labels[arc.getDestination().getId()] = successeur;
|
||||
tas.insert(successeur);
|
||||
|
||||
labelsList[arc.getDestination().getId()] = next;
|
||||
labelsHeap.insert(next);
|
||||
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);
|
||||
|
||||
}else{
|
||||
if (next.getCost() > current.getCost() + data.getCost(arc)) {
|
||||
next.setCost(current.getCost() + data.getCost(arc));
|
||||
next.setFather(arc);
|
||||
try {
|
||||
tas.miseAJour(successeur);
|
||||
}catch(Exception e) {
|
||||
System.out.println("fatal error");
|
||||
}
|
||||
}
|
||||
|
||||
notifyNodeReached(arc.getDestination());
|
||||
}
|
||||
|
||||
}
|
||||
//System.out.println("");
|
||||
}
|
||||
|
||||
|
||||
ShortestPathSolution solution = null;
|
||||
|
||||
//Check if the destination has been reached from the source
|
||||
if (labelsList[data.getDestination().getId()] == null) {
|
||||
//Regarde si la destination a été atteinte et marquée
|
||||
if(labels[data.getDestination().getId()] != null && labels[data.getDestination().getId()].isMarked()) {
|
||||
|
||||
//On récupère tous les arcs constituant le chemin
|
||||
//en partant de la destination et en remontant jusqu'à l'origine
|
||||
ArrayList<Arc> arcsSolution = new ArrayList<>();
|
||||
Arc arc = labels[data.getDestination().getId()].getFather();
|
||||
while(arc != null) {
|
||||
arcsSolution.add(arc);
|
||||
arc = labels[arc.getOrigin().getId()].getFather();
|
||||
}
|
||||
|
||||
Collections.reverse(arcsSolution);
|
||||
|
||||
solution = new ShortestPathSolution(data, Status.OPTIMAL, new Path(graph, arcsSolution));
|
||||
|
||||
//Sinon, il n'y a pas de solution
|
||||
}else {
|
||||
|
||||
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...
|
||||
ArrayList<Arc> arcs = new ArrayList<>();
|
||||
Arc arc = labelsList[data.getDestination().getId()].getFather();
|
||||
while (arc != null) {
|
||||
arcs.add(arc);
|
||||
arc = labelsList[arc.getOrigin().getId()].getFather();
|
||||
}
|
||||
|
||||
// Reverse the arcs' path...
|
||||
Collections.reverse(arcs);
|
||||
|
||||
// Create the final solution.
|
||||
solution = new ShortestPathSolution(data, Status.OPTIMAL, new Path(graph, arcs));
|
||||
}
|
||||
|
||||
System.out.println("nb erreurs = "+cptErreurs);
|
||||
return solution;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,12 +48,6 @@ public class Label implements Comparable<Label>{
|
|||
}
|
||||
@Override
|
||||
public int compareTo(Label o) {
|
||||
if( (this.getCost()-o.getCost() ) < 0) {
|
||||
return -1;
|
||||
}else if( (this.getCost()-o.getCost() ) > 0) {
|
||||
return 1;
|
||||
}else {
|
||||
return 0;
|
||||
}
|
||||
return Double.compare(this.getCost(), o.getCost());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -204,17 +204,44 @@ public class BinaryHeap<E extends Comparable<E>> implements PriorityQueue<E> {
|
|||
}
|
||||
|
||||
|
||||
// public boolean isValid() {
|
||||
//
|
||||
// for(int i=1; i<this.size(); i++) {
|
||||
// E current = this.array.get(i);
|
||||
// E parent = this.array.get(this.indexParent(i));
|
||||
// if( current.compareTo(parent) < 0) {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
//Met à jour l'arbre à partir à partir d'un élément dont le coût a changé
|
||||
public void miseAJour(E x) throws ElementNotFoundException {
|
||||
|
||||
if(this.isEmpty() || x == null){
|
||||
throw new ElementNotFoundException(x);
|
||||
}
|
||||
|
||||
int index = -1;
|
||||
// Iterate over the array and check if the x exists
|
||||
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.
|
||||
|
|
Loading…
Reference in a new issue