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();
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in a new issue