Version Fonctionnelle : Implémentation de la classe Launch, de la fonction IsValid de la classe BinaryHeap. Mise en place du controle de la validité du tas dans Dijkstra (et A*).

This commit is contained in:
Paul Faure 2020-05-11 09:35:35 +02:00
parent 410f1c9a6e
commit 239b501921
4 changed files with 59 additions and 165 deletions

View file

@ -1,161 +1,32 @@
package org.insa.graphs.algorithm.shortestpath;
import org.insa.graphs.model.*;
import java.util.ArrayList;
import java.util.Collections;
import org.insa.graphs.algorithm.AbstractInputData.Mode;
import org.insa.graphs.algorithm.AbstractSolution.Status;
import org.insa.graphs.algorithm.utils.*;
public class AStarAlgorithm extends DijkstraAlgorithm {
public AStarAlgorithm(ShortestPathData data) {
super(data);
}
@Override
protected ShortestPathSolution doRun() {
BinaryHeap<Label> tas = new BinaryHeap<Label>();
final ShortestPathData data = getInputData();
Graph graph = data.getGraph();
Node origin = data.getOrigin();
Node dest = data.getDestination();
int nbNodes = graph.size();
LabelStar[] labels = new LabelStar[nbNodes];
//int nbNonMarque = nbNodes;
int MaxSpeed = data.getMaximumSpeed();
protected void InitialiseLabels(Label[] labels, ShortestPathData data) {
double MaxSpeed = data.getMaximumSpeed();
if (MaxSpeed == -1) {
MaxSpeed = data.getGraph().getGraphInformation().getMaximumSpeed();
}
if (MaxSpeed == -1) {
System.out.println("Toujours -1 !!!!");
}
if (data.getMode() == Mode.LENGTH) {
MaxSpeed = 1;
} else {
MaxSpeed = MaxSpeed / 3.6;
}
for (Node node: graph.getNodes()) {
double estimation = Point.distance(node.getPoint(), dest.getPoint())/MaxSpeed;
for (Node node: data.getGraph().getNodes()) {
double estimation = Point.distance(node.getPoint(), data.getDestination().getPoint())/MaxSpeed;
labels[node.getId()] = new LabelStar(node, estimation);
}
labels[origin.getId()].actualiser(0.0, null);
tas.insert(labels[origin.getId()]);
notifyOriginProcessed(origin);
boolean encore = true;
while ((!labels[dest.getId()].isMarque()) && encore) {
try {
Label current = tas.deleteMin();
int currentID = current.getSommetCourant().getId();
labels[currentID].marquer();
notifyNodeMarked(current.getSommetCourant());
// POUR LE TEST SUR LES COUTS CROISSANTS
// System.out.println(labels[currentID].getCost());
//nbNonMarque--;
// POUR LE TEST SUR LES SUCCESSEURS
//int compteur_successeurs = 0;
for (Arc succ: labels[currentID].getSommetCourant().getSuccessors()) {
// POUR LE TEST SUR LES SUCCESSEURS
//compteur_successeurs++;
if (!data.isAllowed(succ)) {
continue;
}
int succID = succ.getDestination().getId();
if (!labels[succID].isMarque()) {
if (labels[succID].getCost() > (labels[currentID].getCost() + data.getCost(succ))) {
if (labels[succID].getCost() < Double.POSITIVE_INFINITY) {
tas.remove(labels[succID]);
} else {
notifyNodeReached(succ.getDestination());
}
labels[succID].actualiser(labels[currentID].getCost() + data.getCost(succ), succ);
tas.insert(labels[succID]);
}
}
}
// POUR LE TEST SUR LES SUCCESSEURS
/*if (compteur_successeurs != labels[currentID].getSommetCourant().getNumberOfSuccessors()) {
System.out.println("ERREUR Nombre de successeurs visités : " + compteur_successeurs + "/" + labels[currentID].getSommetCourant().getNumberOfSuccessors());
}
System.out.println("Nombre de successeurs visités : " + compteur_successeurs + "/" + labels[currentID].getSommetCourant().getNumberOfSuccessors());
*/
}
catch (EmptyPriorityQueueException e) {
encore = false;
}
catch (ElementNotFoundException e) {
encore = false;
}
}
ShortestPathSolution solution = null;
//Pour le test SOMME(couts) = Cout(Label(Destination))
double SommeCouts = 0.0;
// Destination has no predecessor, the solution is infeasible...
if (labels[dest.getId()].getPere() == null) {
solution = new ShortestPathSolution(data, Status.INFEASIBLE);
}
else {
// The destination has been found, notify the observers.
notifyDestinationReached(dest);
// Create the path from the array of predecessors...
ArrayList<Arc> arcs = new ArrayList<>();
Arc arc = labels[dest.getId()].getPere();
while (arc != null) {
arcs.add(arc);
//Pour le test SOMME(couts) = Cout(Label(Destination))
SommeCouts += data.getCost(arc);
arc = labels[arc.getOrigin().getId()].getPere();
}
// Reverse the path...
Collections.reverse(arcs);
// Create the final solution.
solution = new ShortestPathSolution(data, Status.OPTIMAL, new Path(graph, arcs));
}
if (solution.getStatus() != Status.INFEASIBLE) {
// Test si le path est valide
if (!solution.getPath().isValid()) {
System.out.println("Erreur : PATH SOLUTION INVALID !");
}
// Test s'il correspond a Shortest et Fastest de la classe Path
// INUTILE, SUJET MAL COMPRIS
/*if (data.getMode() == Mode.LENGTH) {
if (solution.getPath().getLength() != Path.createShortestPathFromNodes(graph, solution.getPath().getNodes()).getLength()) {
System.out.println("Erreur : PATH SOLUTION NOT SHORTEST !");
} else {
System.out.println("PATH SOLUTION SHORTEST !");
}
} else {
if (solution.getPath().getMinimumTravelTime() != Path.createFastestPathFromNodes(graph, solution.getPath().getNodes()).getMinimumTravelTime()) {
System.out.println("Erreur : PATH SOLUTION NOT FASTEST !");
} else {
System.out.println("PATH SOLUTION FASTEST !");
}
}*/
if ((int)(SommeCouts * 1000) != (int)(labels[dest.getId()].getCost() * 1000)) {
System.out.println("Erreur : Cost label Dest (" + labels[dest.getId()].getCost() + ") != Somme(cost) (" + SommeCouts + ")");
}
}
return solution;
}
}
}

View file

@ -14,6 +14,12 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
super(data);
}
protected void InitialiseLabels(Label[] labels, ShortestPathData data) {
for (Node node: data.getGraph().getNodes()) {
labels[node.getId()] = new Label(node);
}
}
@Override
protected ShortestPathSolution doRun() {
@ -28,10 +34,7 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
Label[] labels = new Label[nbNodes];
//int nbNonMarque = nbNodes;
for (Node node: graph.getNodes()) {
labels[node.getId()] = new Label(node);
}
this.InitialiseLabels(labels, data);
labels[origin.getId()].actualiser(0.0, null);
tas.insert(labels[origin.getId()]);
@ -49,15 +52,15 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
notifyNodeMarked(current.getSommetCourant());
// POUR LE TEST SUR LES COUTS CROISSANTS
// System.out.println(labels[currentID].getCost());
//System.out.println("Test sur le coût : " + labels[currentID].getTotalCost());
//nbNonMarque--;
// POUR LE TEST SUR LES SUCCESSEURS
//int compteur_successeurs = 0;
int compteur_successeurs = 0;
for (Arc succ: labels[currentID].getSommetCourant().getSuccessors()) {
// POUR LE TEST SUR LES SUCCESSEURS
//compteur_successeurs++;
compteur_successeurs++;
if (!data.isAllowed(succ)) {
continue;
}
@ -73,13 +76,17 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
tas.insert(labels[succID]);
}
}
// TEST SI LE TAS EST TOUJOURS VALIDE
if (!tas.IsValid()) {
System.out.println("ERREUR : Le tas n'est pas valide.");
}
}
// POUR LE TEST SUR LES SUCCESSEURS
/*if (compteur_successeurs != labels[currentID].getSommetCourant().getNumberOfSuccessors()) {
if (compteur_successeurs != labels[currentID].getSommetCourant().getNumberOfSuccessors()) {
System.out.println("ERREUR Nombre de successeurs visités : " + compteur_successeurs + "/" + labels[currentID].getSommetCourant().getNumberOfSuccessors());
}
System.out.println("Nombre de successeurs visités : " + compteur_successeurs + "/" + labels[currentID].getSommetCourant().getNumberOfSuccessors());
*/
//System.out.println("Nombre de successeurs visités : " + compteur_successeurs + "/" + labels[currentID].getSommetCourant().getNumberOfSuccessors());
}
catch (EmptyPriorityQueueException e) {
encore = false;

View file

@ -174,7 +174,17 @@ public class BinaryHeap<E extends Comparable<E>> implements PriorityQueue<E> {
}
public boolean IsValid() {
return true;
boolean valid = true;
int last_element_a_check = (int)(Math.pow(2.0, Math.floor(Math.log(this.currentSize))) - 1);
int i = 0;
while (i < last_element_a_check && valid) {
if ((this.array.get(i).compareTo(this.array.get(this.indexLeft(i))) == 1) || (this.array.get(i).compareTo(this.array.get(this.indexLeft(i) + 1))) == 1) {
valid = false;
} else {
i++;
}
}
return valid;
}
/**

View file

@ -14,6 +14,7 @@ import org.insa.graphs.gui.drawing.components.BasicDrawing;
import org.insa.graphs.model.Graph;
import org.insa.graphs.model.Path;
import org.insa.graphs.model.io.BinaryGraphReader;
import org.insa.graphs.model.io.BinaryPathReader;
import org.insa.graphs.model.io.GraphReader;
import org.insa.graphs.model.io.PathReader;
@ -46,28 +47,33 @@ public class Launch {
public static void main(String[] args) throws Exception {
// Visit these directory to see the list of available files on Commetud.
final String mapName = "/home/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Maps/insa.mapgr";
final String pathName = "/home/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Paths/path_fr31insa_rangueil_r2.path";
final String mapName = "/home/paulfaure/Documents/3A/JAVA/Cartes BE/belgium/europe/belgium.mapgr";
final String pathName = "/home/paulfaure/Documents/3A/JAVA/Paths BE/path_be_173101_302442.path";
// Create a graph reader.
final GraphReader reader = new BinaryGraphReader(
new DataInputStream(new BufferedInputStream(new FileInputStream(mapName))));
// TODO: Read the graph.
final Graph graph = null;
// Read the graph.
final Graph graph = reader.read();
// Create the drawing:
final Drawing drawing = createDrawing();
// TODO: Draw the graph on the drawing.
// Draw the graph on the drawing.
drawing.drawGraph(graph);
// TODO: Create a PathReader.
final PathReader pathReader = null;
// Create a PathReader.
final PathReader pathReader = new BinaryPathReader(new DataInputStream(new BufferedInputStream(new FileInputStream(pathName))));
// TODO: Read the path.
final Path path = null;
// Read the path.
final Path path = pathReader.readPath(graph);
// TODO: Draw the path.
// Draw the path.
drawing.drawPath(path);
reader.close();
pathReader.close();
}
}