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();
// 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;
}

View file

@ -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());
}
}

View file

@ -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.