implementation de l'algo de marathon et amélioration de la classe de tests launch

This commit is contained in:
Tiphaine Pellerin 2026-06-04 18:20:21 +02:00
parent 9c9fb02a9b
commit f12e52c93d
6 changed files with 246 additions and 118 deletions

View file

@ -22,15 +22,15 @@ public class LabelMarathon extends Label implements Comparable<Label> {
return this.coutDest + this.cout; return this.coutDest + this.cout;
} }
public double difMarathon (double d) { public double difMarathon(double d) {
return d - this.getTotalCost() ; return d - this.getTotalCost();
} }
public int compareTo(LabelMarathon l) { public int compareTo(LabelMarathon l) {
if (this.difMarathon (43)< l.difMarathon (43)) { if (this.difMarathon(43) < l.difMarathon(43)) {
return -1; return -1;
} }
else if (this.difMarathon (43)> l.difMarathon (43)) { else if (this.difMarathon(43) > l.difMarathon(43)) {
return 1; return 1;
} }
else { else {
@ -38,4 +38,4 @@ public class LabelMarathon extends Label implements Comparable<Label> {
} }
} }
} }

View file

@ -17,7 +17,8 @@ public class Marathon extends ShortestPathAlgorithm {
} }
public Label newLabelMarathon(Node s, ShortestPathData dataPath) { public Label newLabelMarathon(Node s, ShortestPathData dataPath) {
return new LabelMarathon(s, false, Integer.MAX_VALUE, null, s.getPoint().distanceTo(dataPath.getDestination().getPoint())); return new LabelMarathon(s, false, Integer.MAX_VALUE, null,
s.getPoint().distanceTo(dataPath.getDestination().getPoint()));
} }
@Override @Override
@ -44,11 +45,11 @@ public class Marathon extends ShortestPathAlgorithm {
} }
} }
Node dest = dataInput.getOrigin().getSuccessors().get(0).getDestination() ; Node dest = dataInput.getOrigin().getSuccessors().get(0).getDestination();
Label xl = tas.findMin(); Label xl;
boolean possible = true ; boolean possible = true;
boolean fini = false ; boolean fini = false;
// iterations // iterations
while (!tas.isEmpty() && fini && possible) { while (!tas.isEmpty() && fini && possible) {
@ -56,7 +57,8 @@ public class Marathon extends ShortestPathAlgorithm {
Node x = xl.getSommetCourant(); Node x = xl.getSommetCourant();
notifyNodeMarked(x); notifyNodeMarked(x);
xl.marque = true; xl.marque = true;
possible = false ; possible = false;
tas.remove(xl);
for (Arc a : x.getSuccessors()) { for (Arc a : x.getSuccessors()) {
if (dataInput.isAllowed(a)) { if (dataInput.isAllowed(a)) {
Node n = a.getDestination(); Node n = a.getDestination();
@ -64,43 +66,52 @@ public class Marathon extends ShortestPathAlgorithm {
listLabel[n.getId()] = newLabelMarathon(n, dataInput); listLabel[n.getId()] = newLabelMarathon(n, dataInput);
} }
if (!listLabel[n.getId()].getMarque()) { if (!listLabel[n.getId()].getMarque()) {
possible = true ; possible = true;
listLabel[n.getId()].update(a, listLabel[x.getId()].getCost() + dataInput.getCost(a)); listLabel[n.getId()].update(a,
listLabel[x.getId()].getCost() + dataInput.getCost(a));
if ((!n.equals(dest)) && (listLabel[n.getId()].getCost()) < 43){ if ((!n.equals(dest))
tas.insert(listLabel[n.getId()]) ; && (listLabel[n.getId()].getCost()) < 43) {
tas.insert(listLabel[n.getId()]);
} }
if ((n.equals(dest)) && (42<listLabel[n.getId()].getCost()) && (listLabel[n.getId()].getCost()< 43)){ if ((n.equals(dest)) && (42 < listLabel[n.getId()].getCost())
fini = true ; && (listLabel[n.getId()].getCost() < 43)) {
fini = true;
} }
} }
} }
} }
tas.remove(xl);
} }
// when the algorithm terminates, return the solution that has been found if (!possible) {
if (listLabel[dataInput.getDestination().getId()].getCost() == Double.MAX_VALUE) { System.out.println("erreur : parcours non réalisable\n");
solution = new ShortestPathSolution(dataInput, Status.INFEASIBLE); return null;
} }
else { else {
// The destination has been found, notify the observers. // when the algorithm terminates, return the solution that has been found
notifyDestinationReached(dataInput.getDestination()); if (listLabel[dataInput.getDestination().getId()]
.getCost() == Double.MAX_VALUE) {
// Create the path from the array of predecessors... solution = new ShortestPathSolution(dataInput, Status.INFEASIBLE);
ArrayList<Arc> arcs = new ArrayList<>();
Label nCourant = listLabel[dataInput.getDestination().getId()];
while (nCourant.getPere() != null) {
arcs.add(nCourant.getPere());
nCourant = listLabel[nCourant.getPere().getOrigin().getId()];
} }
// Reverse the path... else {
Collections.reverse(arcs); // The destination has been found, notify the observers.
notifyDestinationReached(dataInput.getDestination());
// Create the final solution. // Create the path from the array of predecessors...
solution = new ShortestPathSolution(dataInput, Status.OPTIMAL, ArrayList<Arc> arcs = new ArrayList<>();
new Path(graph, arcs)); Label nCourant = listLabel[dataInput.getDestination().getId()];
while (nCourant.getPere() != null) {
arcs.add(nCourant.getPere());
nCourant = listLabel[nCourant.getPere().getOrigin().getId()];
}
// Reverse the path...
Collections.reverse(arcs);
// Create the final solution.
solution = new ShortestPathSolution(dataInput, Status.OPTIMAL,
new Path(graph, arcs));
}
return solution;
} }
return solution;
} }
} }

View file

@ -5,11 +5,11 @@ import java.awt.Dimension;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.util.Random;
import javax.swing.JFrame; import javax.swing.JFrame;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import org.insa.graphs.algorithm.ArcInspector;
import org.insa.graphs.algorithm.ArcInspectorFactory; import org.insa.graphs.algorithm.ArcInspectorFactory;
import org.insa.graphs.algorithm.shortestpath.AStarAlgorithm; import org.insa.graphs.algorithm.shortestpath.AStarAlgorithm;
import org.insa.graphs.algorithm.shortestpath.BellmanFordAlgorithm; import org.insa.graphs.algorithm.shortestpath.BellmanFordAlgorithm;
@ -19,11 +19,12 @@ import org.insa.graphs.algorithm.shortestpath.ShortestPathSolution;
import org.insa.graphs.gui.drawing.Drawing; import org.insa.graphs.gui.drawing.Drawing;
import org.insa.graphs.gui.drawing.components.BasicDrawing; import org.insa.graphs.gui.drawing.components.BasicDrawing;
import org.insa.graphs.model.Graph; import org.insa.graphs.model.Graph;
import org.insa.graphs.model.Node;
import org.insa.graphs.model.Path; import org.insa.graphs.model.Path;
import org.insa.graphs.model.io.BinaryGraphReader; 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.GraphReader;
import org.insa.graphs.model.io.PathReader;
import org.insa.graphs.gui.simple.ExceptionCheminImpossible;
public class Launch { public class Launch {
@ -32,6 +33,7 @@ public class Launch {
* *
* @return The created drawing. * @return The created drawing.
* @throws Exception if something wrong happens when creating the graph. * @throws Exception if something wrong happens when creating the graph.
* @throws ExceptionCheminImpossible
*/ */
public static Drawing createDrawing() throws Exception { public static Drawing createDrawing() throws Exception {
BasicDrawing basicDrawing = new BasicDrawing(); BasicDrawing basicDrawing = new BasicDrawing();
@ -50,110 +52,225 @@ public class Launch {
return basicDrawing; return basicDrawing;
} }
private static ShortestPathSolution paths ; private static ShortestPathSolution paths;
private static ShortestPathSolution paths2 ; private static ShortestPathSolution paths2;
private static ShortestPathSolution paths3 ; private static ShortestPathSolution paths3;
private static DijkstraAlgorithm dijkstra ; private static DijkstraAlgorithm dijkstra;
private static BellmanFordAlgorithm bellman ; private static BellmanFordAlgorithm bellman;
private static AStarAlgorithm AEtoile ; private static AStarAlgorithm AEtoile;
private static ShortestPathData data ; private static ShortestPathData data;
public static void main(String[] args) throws Exception {
// visit these directory to see the list of available files on commetud. public static void main(String[] args) throws Exception, ExceptionCheminImpossible {
final String[] mapName ={
"/mnt/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Maps/insa.mapgr", // Chemins vers les cartes (les fichiers .path ne sont plus nécessaires ici)
"/mnt/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Maps/toulouse.mapgr", final String[] mapName = {
"/mnt/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Maps/toulouse.mapgr", "/mnt/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Maps/toulouse.mapgr",
"/mnt/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Maps/france.mapgr" "/mnt/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Maps/insa.mapgr",
}; "/mnt/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Maps/toulouse.mapgr",
final String[] pathName = { "/mnt/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Maps/france.mapgr" };
"/mnt/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Paths/path_fr31insa_rangueil_r2.path",
"/mnt/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Paths/path_fr31_insa_bikini_motorcar.path",
"/mnt/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Paths/path_fr31_insa_bikini_canal.path",
"/mnt/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Paths/path_fr_insa_tour.path"
};
final Graph[] graph = new Graph[4]; final Graph[] graph = new Graph[4];
final Path[] path = new Path[4]; Random rand = new Random();
for (int i = 0 ; i<4 ; i++) { // for (int i = 0; i < 4; i++) {
// create a graph reader // Lecture du graphe
try (final GraphReader reader = new BinaryGraphReader(new DataInputStream( try (final GraphReader reader = new BinaryGraphReader(new DataInputStream(
new BufferedInputStream(new FileInputStream(mapName[i]))))) { new BufferedInputStream(new FileInputStream(mapName[0]))))) {
// TODO: read the graph graph[0] = reader.read();
graph[i] = reader.read(); System.out.println("Carte chargée avec succès : " + mapName[0]);
System.out.println("pas d'erreur au niveau du reader"); }
}
// create the drawing // Création de l'affichage graphique
final Drawing drawing = createDrawing(); final Drawing drawing = createDrawing();
drawing.drawGraph(graph[0]);
// TODO: draw the graph on the drawing // Nombre de nœuds maximum disponibles sur cette carte
drawing.drawGraph(graph[i]); int numNodes = graph[0].getNodes().size()-1;
// TODO: create a path reader // --- DEBUT DES TESTS ALEATOIRES ---
try (final PathReader pathReader = new BinaryPathReader(new DataInputStream( // On crée 10 paires de points aléatoires pour chaque carte
new BufferedInputStream(new FileInputStream(pathName[i]))))) { int nbTests = 2;
for (int t = 1; t <= nbTests; t++) {
// TODO: read the path // Choix de l'origine et de la destination
path[i] = pathReader.readPath(graph[i]); Node origin = graph[0].getNodes().get(rand.nextInt(numNodes));
System.out.println("pas d'erreur au niveau du pathreader"); Node destination = graph[0].getNodes().get(rand.nextInt(numNodes));
}
// TODO: draw the path on the drawing System.out.println(
drawing.drawPath(path[i]); String.format("\n[Test %d/%d] Origine ID: %d | Destination ID: %d",
t, nbTests, origin.getId(), destination.getId()));
data = new ShortestPathData(graph[i], path[i].getOrigin(),path[i].getDestination(), ArcInspectorFactory.getAllFilters().get(i)) ;
dijkstra = new DijkstraAlgorithm(data) ; data = new ShortestPathData(graph[0], origin, destination,
ArcInspectorFactory.getAllFilters().get(1));
dijkstra = new DijkstraAlgorithm(data);
bellman = new BellmanFordAlgorithm(data); bellman = new BellmanFordAlgorithm(data);
AEtoile = new AStarAlgorithm(data) ; AEtoile = new AStarAlgorithm(data);
paths = dijkstra.doRun() ;
paths2 = bellman.doRun() ;
paths3 = AEtoile.doRun() ;
if (!paths.getPath().isValid()){ paths = dijkstra.doRun();
System.out.println("Pour la carte " + i + ", c'est pas valide"); paths2 = bellman.doRun();
paths3 = AEtoile.doRun();
if (!paths.isFeasible()) { // --- VERIFICATION ET COMPARAISON DES RESULTATS ---
System.out.println("Chemin impossible");
// Cas 1 : Aucun chemin trouvé par Dijkstra
if (!paths.isFeasible() || paths.getPath() == null) {
System.out.println("\n Dijkstra : Aucun chemin trouvé (Infeasible).");
// Alerte de sécurité si un autre algo prétend en trouver un
if (paths2.isFeasible() || paths3.isFeasible()) {
System.out.println(
"\n Bellman ou A* ont trouvé un chemin alors que Dijkstra dit que c'est impossible !");
} }
throw new ExceptionCheminImpossible("pas de chemin possible");
} }
// Cas 2 : Un chemin a été trouvé
else { else {
System.out.println("Pour la carte " + i + ", c'est valide"); System.out.println("\n Dijkstra : Chemin trouvé !");
if (paths.isFeasible()) {
System.out.println("Chemin possible"); // Cas particulier : Origine égale à la destination
} if (origin.equals(destination)) {
//tester si l'origine = destination System.out.println("\n L'origine est égale à la destination.");
if (paths.getInputData().getOrigin() == paths.getInputData().getDestination()) {
System.out.println("Origine = destination");
} }
if (Math.abs(paths.getPath().getLength()- paths2.getPath().getLength()) < 1e-6) { Path pDijkstra = paths.getPath();
System.out.println("Même résultat entre dijkstra et bellman"); Path pBellman = paths2.getPath();
Path pAStar = paths3.getPath();
// Affichage du chemin de Dijkstra sur l'interface
drawing.drawPath(pDijkstra);
// Comparaison des algos Dijkstra et Bellman-Ford
if (pBellman != null) {
// test sur les distances (on laisse 1 cm de marge)
if (Math.abs(pDijkstra.getLength() - pBellman.getLength()) < 1e-2) {
System.out
.println("\n Même distance entre Dijkstra et Bellman");
}
else {
float diff =
Math.abs(pDijkstra.getLength() - pBellman.getLength());
System.out.println(
"\n Distance différente entre Dijkstra et Bellman --> différence de"
+ diff);
}
// test sur le temps de parcours (on laisse 1 seconde de marge)
if (Math.abs(pDijkstra.getMinimumTravelTime()
- pBellman.getMinimumTravelTime()) < 1.0) {
System.out.println(
"\n Même temps de parcours entre Dijkstra et Bellman");
}
else {
double diff = Math.abs(pDijkstra.getMinimumTravelTime()
- pBellman.getMinimumTravelTime());
System.out.println(
"\n Temps différents entre Dijkstra et Bellman --> différence de"
+ diff);
}
} }
else { else {
System.out.println("Résultat différent entre dijkstra et A*"); System.out.println(
"\n Probleme : Bellman n'a trouvé aucun chemin alors que Dijkstra oui.");
} }
if (Math.abs(paths.getPath().getLength()- paths3.getPath().getLength()) < 1e-6) { // Comparaison des algos Dijkstra et A*
System.out.println("Même résultat entre dijkstra et A*"); if (pAStar != null) {
}else { // test sur les distances
System.out.println("Résultat différent entre dijkstra et A*"); if (Math.abs(pDijkstra.getLength() - pAStar.getLength()) < 1e-2) {
System.out.println("\n Même distance entre Dijkstra et A* ");
}
else {
float diff2 =
Math.abs(pDijkstra.getLength() - pAStar.getLength());
System.out.println(
" Distance différente entre Dijkstra et A* --> différence de "
+ diff2);
}
// test sur le temps de parcours
if (Math.abs(pDijkstra.getMinimumTravelTime()
- pAStar.getMinimumTravelTime()) < 1.0) {
System.out.println(
"\n Même temps de parcours entre Dijkstra et A*");
}
else {
double diff2 = Math.abs(pDijkstra.getMinimumTravelTime()
- pAStar.getMinimumTravelTime());
System.out.println(
"\n Temps différents entre Dijkstra et A* --> différence de"
+ diff2);
}
} }
else {
System.out.println(
if (i==2) { //on teste au niveau du temps --> demande un ArcInspectorFactory spécial "\n Probleme : A* n'a trouvé aucun chemin alors que Dijkstra oui.");
if (Math.abs(paths.getPath().getMinimumTravelTime()- paths2.getPath().getMinimumTravelTime()) < 1e-6) {
System.out.println("Même résultat");
}
if (paths.getPath().getMinimumTravelTime()==paths2.getPath().getMinimumTravelTime()) {
System.out.println("Dijkstra donne le même résultat que Bellman");
}
} }
} }
} }
}
} // --- CAS : CHEMIN IMPOSSIBLE ---
// PAS FINI (points à récup sur carte)
Node origin = graph[0].getNodes().get(27869);
Node destination = graph[0].getNodes().get(14534);
System.out.println(String.format(
"\n[Test chemin impossible] Origine ID: %d | Destination ID: %d",
origin.getId(), destination.getId()));
data = new ShortestPathData(graph[0], origin, destination,
ArcInspectorFactory.getAllFilters().get(0));
dijkstra = new DijkstraAlgorithm(data);
bellman = new BellmanFordAlgorithm(data);
AEtoile = new AStarAlgorithm(data);
paths = dijkstra.doRun();
paths2 = bellman.doRun();
paths3 = AEtoile.doRun();
// --- VERIFICATION ---
if (!paths.isFeasible() || paths.getPath() == null) {
System.out.println("\n Dijkstra : Aucun chemin trouvé (Infeasible).");
// Alerte de sécurité si un autre algo prétend en trouver un
if (paths2.isFeasible() || paths3.isFeasible()) {
System.out.println(
"\n Bellman ou A* ont trouvé un chemin alors que Dijkstra dit que c'est impossible !");
}
throw new ExceptionCheminImpossible("pas de chemin possible");
}
// CAS : DEPART = ARRIVEE
Node origine = graph[0].getNodes().get(rand.nextInt(numNodes));
Node destinations = origine;
System.out.println(String.format(
"\n[Test origine = dest] Origine ID: %d | Destination ID: %d",
origine.getId(), destinations.getId()));
data = new ShortestPathData(graph[0], origine, destinations,
ArcInspectorFactory.getAllFilters().get(0));
dijkstra = new DijkstraAlgorithm(data);
bellman = new BellmanFordAlgorithm(data);
AEtoile = new AStarAlgorithm(data);
paths = dijkstra.doRun();
paths2 = bellman.doRun();
paths3 = AEtoile.doRun();
// --- VERIFICATION ---
System.out.println("\n Dijkstra : Chemin trouvé !");
// Cas particulier : Origine égale à la destination
if (origine.equals(destinations)) {
System.out.println("\n L'origine est égale à la destination.");
}
// --- FIN DES TESTS ALEATOIRES POUR CETTE CARTE ---
// }
}
}