Merge branch 'main' of https://git.etud.insa-toulouse.fr/bezza/BE-Graphe
This commit is contained in:
commit
ef88c3e14f
7 changed files with 271 additions and 44 deletions
|
|
@ -9,7 +9,8 @@ public class AStarAlgorithm extends DijkstraAlgorithm {
|
|||
|
||||
@Override
|
||||
protected LabelStar createLabel(Node node) {
|
||||
return new LabelStar(node, false, Double.POSITIVE_INFINITY, null, getInputData().getDestination());
|
||||
ShortestPathData data = getInputData(); //pour récupérer la vitesse maximale du graphe, la destination et si on est en fastestpath ou shortestpath
|
||||
return new LabelStar(node, false, Double.POSITIVE_INFINITY,null,data);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import org.insa.graphs.model.Arc;
|
|||
import org.insa.graphs.model.Graph;
|
||||
import org.insa.graphs.model.Node;
|
||||
import org.insa.graphs.model.Path;
|
||||
|
||||
import org.insa.graphs.model.RoadInformation.RoadType;
|
||||
|
||||
public class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
||||
|
||||
|
|
@ -21,6 +21,29 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
|||
return new Label(node, false, Double.POSITIVE_INFINITY, null);
|
||||
}
|
||||
|
||||
protected void tryUpdateLabel(Label[] labels, BinaryHeap<Label> heap, Node node,
|
||||
double newCost, Arc pere) {
|
||||
|
||||
Label label = labels[node.getId()];
|
||||
|
||||
if (newCost < label.getCoutRealise()) {
|
||||
if (label.getCoutRealise() != Double.POSITIVE_INFINITY) {
|
||||
heap.remove(label);
|
||||
}
|
||||
|
||||
label.setCoutRealise(newCost);
|
||||
label.setPere(pere);
|
||||
|
||||
heap.insert(label);
|
||||
notifyNodeReached(node);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void fonctionProblemeOuvert(RoadType typeDeRoute,Label[] labels, BinaryHeap<Label> heap, Node node,
|
||||
double newCost, Arc pere){}
|
||||
|
||||
|
||||
@Override
|
||||
protected ShortestPathSolution doRun() {
|
||||
|
|
@ -75,21 +98,10 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm {
|
|||
// Correction ici : on utilise getCoutRealise() pour Dijkstra
|
||||
double newCost = LabelActuel.getCoutRealise() + data.getCost(arc);
|
||||
|
||||
if (newCost < succLabel.getCoutRealise()) {
|
||||
if (succLabel.getCoutRealise() != Double.POSITIVE_INFINITY) {
|
||||
heap.remove(succLabel);
|
||||
//System.out.println(succLabel.getTotalCost());// print de confirmation , pour verif si tous les couts qui sortent du tas sont croissant. getTotalcost pas croissant!!
|
||||
}
|
||||
succLabel.setCoutRealise(newCost);
|
||||
succLabel.setPere(arc);
|
||||
predecessorArcs[succ.getId()] = arc;
|
||||
tryUpdateLabel(labels, heap, succ, newCost, arc);
|
||||
|
||||
// Insertion dans le tas car on est sûr qu'il n'est pas
|
||||
fonctionProblemeOuvert(arc.getRoadInformation().getType(),labels, heap, succ, newCost, arc); //fonction uniquement pour probleme ouvert, permet de ne pas réécrire l'algorithme pour le problème ouvert
|
||||
|
||||
heap.insert(succLabel);
|
||||
|
||||
notifyNodeReached(succ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
/*public class LabelProblemeOuvert extends Label {
|
||||
private double autonomieRestante;
|
||||
|
||||
public LabelProblemeOuvert(Node sommet, boolean marque, double cout, Arc pere, double autonomieRestante) {
|
||||
super(sommet, marque, cout, pere);
|
||||
this.autonomieRestante = autonomieRestante;
|
||||
}
|
||||
|
||||
public double getAutonomieRestante() {
|
||||
return autonomieRestante;
|
||||
}
|
||||
|
||||
public void setAutonomieRestante(double autonomieRestante) {
|
||||
this.autonomieRestante = autonomieRestante;
|
||||
}
|
||||
}*/
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package org.insa.graphs.algorithm.shortestpath;
|
||||
|
||||
import org.insa.graphs.model.Arc;
|
||||
import org.insa.graphs.model.Node;
|
||||
|
||||
public class LabelProblemeOuvert extends Label {
|
||||
private double autonomieRestante; //double pour la cohérence avec les autres couts qui sont en double eux aussi
|
||||
|
||||
public LabelProblemeOuvert(Node sommet, boolean marque, double cout, Arc pere, double autonomieRestante) {
|
||||
super(sommet, marque, cout, pere);
|
||||
this.autonomieRestante = autonomieRestante;
|
||||
}
|
||||
|
||||
public double getAutonomieRestante() {
|
||||
return autonomieRestante;
|
||||
}
|
||||
|
||||
public void setAutonomieRestante(double autonomieRestante) {
|
||||
this.autonomieRestante = autonomieRestante;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getTotalCost() { //normalement pas besoin
|
||||
return this.getCoutRealise();
|
||||
}
|
||||
|
||||
/*@Override
|
||||
public int compareTo(LabelProblemeOuvert other) {
|
||||
return Double.compare(this.getTotalCost(), other.getTotalCost());
|
||||
}*/
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package org.insa.graphs.algorithm.shortestpath;
|
||||
|
||||
import org.insa.graphs.algorithm.AbstractInputData;
|
||||
import org.insa.graphs.model.Arc;
|
||||
import org.insa.graphs.model.Node;
|
||||
import org.insa.graphs.model.Point;
|
||||
|
|
@ -7,30 +8,70 @@ import org.insa.graphs.model.Point;
|
|||
|
||||
|
||||
public class LabelStar extends Label {
|
||||
|
||||
private Node destination;
|
||||
public LabelStar(Node sommetCourant, Boolean marque, double coutRealise, Arc pere,Node destination) {
|
||||
;
|
||||
private ShortestPathData pathData;
|
||||
public LabelStar(Node sommetCourant, Boolean marque, double coutRealise, Arc pere, ShortestPathData data) {
|
||||
super(sommetCourant, marque, coutRealise, pere);
|
||||
this.destination=destination;
|
||||
this.pathData = data; //pour récupérer la vitesse maximale du graphe, la destination et si on est en fastestpath ou shortestpath
|
||||
}
|
||||
|
||||
|
||||
//pour optimiser l'algo : ATTENTION PAS à L'initialisation pas le faire sinon ça va le faire pr tout les pts
|
||||
//on rajoute un paremètre distance ds le label et quand on passe sur le label si c'est linfini on le calcule
|
||||
|
||||
@Override
|
||||
/*@Override
|
||||
public double getTotalCost() { //pourquoi getTotalCost ? psq il est utilisé dans le compareTo
|
||||
//System.out.println("cout realise : " + getCoutRealise()+ "\n distance : "distance(getSommetCourant().getPoint(),this.destination.getPoint()));
|
||||
double cout=getCoutRealise();
|
||||
Point calcul = this.destination.getPoint();
|
||||
Point calcul = this.pathData.getDestination().getPoint();
|
||||
cout+=calcul.distanceTo(this.getSommetCourant().getPoint());
|
||||
return (cout);
|
||||
}
|
||||
}*/
|
||||
|
||||
//pas nécessaire normalement
|
||||
/*public int compareTo(LabelStar other) {
|
||||
return Double.compare(this.getTotalCost(), other.getTotalCost());
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Calcule le coût total estimé (f = g + h) pour l'algorithme A*.
|
||||
* g (getCoutRealise()) est le coût actuel depuis le départ.
|
||||
* h est l'heuristique :
|
||||
* - En mode DISTANCE: distance à vol d'oiseau (via distanceTo) jusqu'à la destination.
|
||||
* - En mode TEMPS: distance à vol d'oiseau (via distanceTo) / vitesse maximale sur le graphe.
|
||||
* @return Le coût total estimé.
|
||||
*/
|
||||
@Override
|
||||
public double getTotalCost() {
|
||||
double gCost = getCoutRealise(); // Coût actuel depuis l'origine (distance ou temps)
|
||||
double hCost = 0.0;
|
||||
|
||||
Node current = getSommetCourant();
|
||||
Node destinationNode = this.pathData.getDestination(); // Obtention de la destination depuis pathData
|
||||
Point currentPoint = current.getPoint();
|
||||
Point destinationPoint = destinationNode.getPoint();
|
||||
if (currentPoint == null || destinationPoint == null) {
|
||||
return gCost; // Heuristique nulle si points non valides
|
||||
}
|
||||
|
||||
//calcul vol d'oiseau
|
||||
double distanceToDestinationMeters = currentPoint.distanceTo(destinationPoint);
|
||||
|
||||
//différencier TIME et DISTANCE
|
||||
if (this.pathData.getMode() == AbstractInputData.Mode.TIME) {
|
||||
int maxSpeedKmH = this.pathData.getGraph().getGraphInformation().getMaximumSpeed();
|
||||
|
||||
// Conversion de la vitesse max en mètres par seconde (m/s)
|
||||
double maxSpeedMpS = maxSpeedKmH / 3.6;
|
||||
hCost = distanceToDestinationMeters / maxSpeedMpS; // hCost est maintenant en secondes
|
||||
|
||||
} else {
|
||||
// Heuristique pour le mode DISTANCE (ou par défaut)
|
||||
hCost = distanceToDestinationMeters; // hCost est en mètres
|
||||
}
|
||||
|
||||
return gCost + hCost;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -106,3 +106,153 @@ gérer le problème de la recharge, quand la faire ?
|
|||
*/
|
||||
|
||||
|
||||
package org.insa.graphs.algorithm.shortestpath;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.insa.graphs.algorithm.AbstractSolution.Status;
|
||||
import org.insa.graphs.algorithm.utils.BinaryHeap;
|
||||
import org.insa.graphs.model.Arc;
|
||||
import org.insa.graphs.model.Graph;
|
||||
import org.insa.graphs.model.Node;
|
||||
import org.insa.graphs.model.Path;
|
||||
import org.insa.graphs.model.RoadInformation.RoadType;
|
||||
//import org.insa.graphs.algorithm.shortestpath.ProblemeOuvert;
|
||||
|
||||
public class ProblemeOuvert extends DijkstraAlgorithm {
|
||||
|
||||
|
||||
private double MAX_BATTERY = 200;
|
||||
|
||||
public ProblemeOuvert(ShortestPathData data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LabelProblemeOuvert createLabel(Node node) {
|
||||
return new LabelProblemeOuvert(node, false, Double.POSITIVE_INFINITY, null, MAX_BATTERY);
|
||||
}
|
||||
|
||||
protected void tryUpdateLabel(LabelProblemeOuvert[] labels, BinaryHeap<Label> heap, Node node,
|
||||
double newCost, double newBatteryLeft, Arc pere, Arc[] tableauArcs) {
|
||||
|
||||
LabelProblemeOuvert label = labels[node.getId()];
|
||||
|
||||
if (newCost < label.getCoutRealise()) {
|
||||
if (label.getCoutRealise() != Double.POSITIVE_INFINITY) {
|
||||
heap.remove(label);
|
||||
}
|
||||
|
||||
label.setCoutRealise(newCost);
|
||||
label.setAutonomieRestante(newBatteryLeft);
|
||||
label.setPere(pere);
|
||||
|
||||
tableauArcs[pere.getDestination().getId()] = pere;
|
||||
|
||||
heap.insert(label);
|
||||
notifyNodeReached(node);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*@Override
|
||||
protected void fonctionProblemeOuvert(RoadType typeDeRoute,LabelProblemeOuvert[] labels, BinaryHeap<LabelProblemeOuvert> heap, Node node,
|
||||
double newCost, Arc pere){
|
||||
if (typeDeRoute == RoadType.MOTORWAY) {
|
||||
tryUpdateLabel(labels, heap,node, newCost, MAX_BATTERY, pere);
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
@Override
|
||||
protected ShortestPathSolution doRun() {
|
||||
|
||||
final ShortestPathData data = getInputData();
|
||||
ShortestPathSolution solution = null;
|
||||
// accès au graphe
|
||||
Graph graph = data.getGraph();
|
||||
int nbNodes = graph.size();
|
||||
|
||||
// Tableau des labels pour chaque sommet
|
||||
LabelProblemeOuvert[] labels = new LabelProblemeOuvert[nbNodes];
|
||||
// Tableau des arcs prédécesseurs pour reconstruire le chemin
|
||||
Arc[] predecessorArcs = new Arc[nbNodes];
|
||||
|
||||
// Initialisation des labels
|
||||
for (Node node : graph.getNodes()) {
|
||||
labels[node.getId()] =createLabel(node);
|
||||
}
|
||||
// Origine : coût 0, non marqué, pas de père
|
||||
labels[data.getOrigin().getId()].setCoutRealise(0);
|
||||
|
||||
BinaryHeap<Label> heap = new BinaryHeap<>();
|
||||
heap.insert(labels[data.getOrigin().getId()]);
|
||||
|
||||
notifyOriginProcessed(data.getOrigin());
|
||||
|
||||
while (!heap.isEmpty()) {
|
||||
Label LabelActuel = heap.deleteMin();
|
||||
Node NodeActuel = LabelActuel.getSommetCourant();
|
||||
|
||||
// sommet traité
|
||||
LabelActuel.setMarque(true);
|
||||
|
||||
// On a atteint la destination on s'arrête
|
||||
if (NodeActuel.equals(data.getDestination())) {
|
||||
notifyDestinationReached(NodeActuel);
|
||||
break;
|
||||
}
|
||||
|
||||
// Pour chaque successeur
|
||||
for (Arc arc : NodeActuel.getSuccessors()) {
|
||||
if (!data.isAllowed(arc)) continue; // ici c'est pour l'amélioration voiture ou a pied
|
||||
|
||||
|
||||
Node succ = arc.getDestination();
|
||||
LabelProblemeOuvert succLabel = labels[succ.getId()];
|
||||
|
||||
if (succLabel.getMarque()) continue;
|
||||
|
||||
double arcCost = data.getCost(arc);
|
||||
double batteryLeft = ((LabelProblemeOuvert) LabelActuel).getAutonomieRestante();
|
||||
|
||||
if (batteryLeft < arcCost) continue; // Pas assez de batterie pour ce chemin
|
||||
|
||||
double newCost = LabelActuel.getCoutRealise() + arcCost;
|
||||
double newBatteryLeft = batteryLeft - arcCost;
|
||||
|
||||
// 1. On fais le test d'avant qui vérfie si le coût avec ce chemin est meilleur
|
||||
tryUpdateLabel(labels, heap, succ, newCost, newBatteryLeft, arc,predecessorArcs);
|
||||
|
||||
// 2. On fait aussi le test avec une autonmie pleine pour voir si la solution est meilleure (il faudra rajouter 2mn au temps de trajet)
|
||||
//si on recharge effectivement et détecter cette recharge
|
||||
if (arc.getRoadInformation().getType() == RoadType.MOTORWAY) {
|
||||
tryUpdateLabel(labels, heap, succ, newCost, MAX_BATTERY, arc,predecessorArcs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Construction de la solution
|
||||
if (predecessorArcs[data.getDestination().getId()] == null) {
|
||||
solution = new ShortestPathSolution(data, Status.INFEASIBLE);
|
||||
}
|
||||
else {
|
||||
// Reconstruire le chemin
|
||||
ArrayList<Arc> arcs = new ArrayList<>();
|
||||
Arc arc = predecessorArcs[data.getDestination().getId()];
|
||||
while (arc != null) {
|
||||
arcs.add(arc);
|
||||
arc = predecessorArcs[arc.getOrigin().getId()];
|
||||
}
|
||||
Collections.reverse(arcs);// on inverse le chemin
|
||||
solution = new ShortestPathSolution(data, Status.OPTIMAL,new Path(graph, arcs));
|
||||
}
|
||||
|
||||
return solution;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -79,6 +79,12 @@ public class TestDijkstra {
|
|||
break;
|
||||
}
|
||||
|
||||
// Affichage graphique
|
||||
final Drawing drawing = Launch.createDrawing();
|
||||
//On utilise les observateurs pour Astar
|
||||
|
||||
drawing.drawGraph(graph);
|
||||
|
||||
|
||||
ShortestPathSolution solution = dijkstra.run();
|
||||
|
||||
|
|
@ -151,11 +157,8 @@ public class TestDijkstra {
|
|||
}
|
||||
}
|
||||
|
||||
// Affichage graphique
|
||||
// final Drawing drawing = createDrawing();
|
||||
// drawing.drawGraph(graph);
|
||||
// drawing.drawPath(path);
|
||||
|
||||
drawing.drawPath(path);
|
||||
} else {
|
||||
System.out.println("Aucun chemin trouvé.");
|
||||
}
|
||||
|
|
@ -174,10 +177,15 @@ public class TestDijkstra {
|
|||
//cartes routières
|
||||
System.out.println("== Test en distance ==");
|
||||
testScenario("insa.mapgr", 369, 838, Mode.LENGTH, true,0,false);
|
||||
// System.out.println("== Test en distance ==");
|
||||
// testScenario("insa.mapgr", 369, 838, Mode.LENGTH, true,false,false);
|
||||
|
||||
System.out.println("== Test en temps ==");
|
||||
testScenario("insa.mapgr", 369, 838, Mode.TIME, true,0,false);
|
||||
// autres scénarios
|
||||
// System.out.println("== Test en temps ==");
|
||||
// testScenario("insa.mapgr", 369, 838, Mode.TIME, true,false,false);
|
||||
// // autres scénarios
|
||||
|
||||
// System.out.println("== Trajet long (et pénible avec les enfants) ==");
|
||||
// testScenario("bretagne.mapgr",564429,602395 , Mode.LENGTH, false,false,false);
|
||||
|
|
|
|||
Loading…
Reference in a new issue