diff --git a/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/LabelProblemeOuvert.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/LabelProblemeOuvert.java index 3135919..5497db5 100644 --- a/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/LabelProblemeOuvert.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/LabelProblemeOuvert.java @@ -5,10 +5,13 @@ 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 + //private int temps; + public LabelProblemeOuvert(Node sommet, boolean marque, double cout, Arc pere, double autonomieRestante) { super(sommet, marque, cout, pere); this.autonomieRestante = autonomieRestante; + //this.temps=temps; } public double getAutonomieRestante() { @@ -18,4 +21,13 @@ public class LabelProblemeOuvert extends Label { public void setAutonomieRestante(double autonomieRestante) { this.autonomieRestante = autonomieRestante; } + + /* + public int getTemps() { + return temps; + } + + public void setTemps(int temps) { + this.temps = temps; + }*/ } diff --git a/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/ProblemeOuvert.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/ProblemeOuvert.java index 162c4c3..0d4502f 100644 --- a/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/ProblemeOuvert.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/ProblemeOuvert.java @@ -1,99 +1,3 @@ - - - -/* je considère que les 200km d'autonomie atteint (200km avec le 22 kWh - Q90 Renault ZOE chargé à 90%) - cette autonomie est considéré en ville à 200km (à 30km/h de moyenne) - en mixte elle devient 154 km (47km/h de moyenne) ~3/4 de l'autonmie - en autoroute uniquement 102 km (120km/h de moyenne) ~1/2 de l'autonomie - - Problème il y a 20 types de ROADTYPE : - - Routes principales - - MOTORWAY : Autoroute — voie rapide, à accès contrôlé, sans intersections à niveau, souvent interdite aux piétons, cyclistes, etc. - - TRUNK : Route principale (quasi autoroute) — grande route interurbaine importante, parfois à accès limité, avec peu d’intersections. - - PRIMARY : Route nationale — dessert les grandes villes, avec un trafic important, mais moins prioritaire qu'une "trunk". - - SECONDARY : Route secondaire — relie des villes moyennes ou des centres régionaux. - - TERTIARY : Route tertiaire — dessert des petites villes ou relie des routes secondaires. - -Branches ou bretelles - - MOTORWAY_LINK : Bretelle d’accès ou de sortie d’autoroute. - - TRUNK_LINK : Bretelle ou jonction vers une route "trunk". - - PRIMARY_LINK : Bretelle reliant une route "primary". - - SECONDARY_LINK : Bretelle reliant une route "secondary". - -Réseau local - - RESIDENTIAL : Rue résidentielle — dans un quartier d’habitation, circulation modérée. - - UNCLASSIFIED : Petite route rurale ou de desserte locale, souvent utilisée par défaut si la classification est inconnue. - - LIVING_STREET : Rue résidentielle apaisée — priorité aux piétons, vitesse très réduite (zone de rencontre). - - SERVICE : Voie de service — accès à des bâtiments, parkings, zones industrielles ou fermes. - -Autres types de voies - - ROUNDABOUT : Rond-point — configuration de carrefour circulaire, souvent classée selon le type de route qu’elle relie. - - PEDESTRIAN : Rue piétonne — réservée principalement ou exclusivement aux piétons. - - CYCLEWAY : Piste cyclable — voie dédiée aux vélos. - - TRACK : Chemin agricole ou forestier — destiné aux véhicules tout-terrain ou agricoles, pas pour le trafic général. - - COASTLINE : Littoral — ligne représentant la côte, utilisée pour délimiter les terres et les mers (pas une route au sens circulable). - - - Donc en fonction de chaque roadtype il faudrait définir quelle autnomie nous avons. Par exemple si on fait de l'autoroute, 1km = 2km d'autonomie - - Après avoir fait les ratios pour chaque roadType qu'on peut obtenir dans roadInformation dans chaque Arc parcouru - - getMinimumTravelTime et getLenght*autonomieSurCeRoadType pour l'autonomie qu'on perd pour chaque arc - - => pour simplifier les choses on va estimer qu'on roule toujours à la vitesse maximale autorisée - comme cela on peut avoir le TravelTime avec getTravelTime pour pour le chemin le plus court - et nous n'avons pas besoin d'associer une vitesse à chaque roadtype, juste une perte d'autonomie - - //Rappel les bornes de recharges ne sont que sur les autoroutes ! - => va falloir prévilégier l'autoroute ? Ce sera fait implicitement : - - .Pour le temps : Comme on suppose rouler à la vitesse maximale autorisée, et que les autoroutes ont les vitesses les plus élevées, getMinimumTravelTime() - sera naturellement plus bas pour les arcs d'autoroute, les favorisant si l'objectif est le temps. - - .Pour la recharge : Le fait que les recharges ne soient possibles que sur les autoroutes rendra leur utilisation nécessaire pour les longs trajets. - L'algorithme, en explorant les états (y compris ceux après recharge), déterminera si un détour par une autoroute pour recharger et ensuite continuer - (potentiellement plus vite) est la meilleure solution globale. - - - concrètement dans le Dijkstra il va falloir rajouter une composante. Après le if 'newCost <'... - il faut vérifier que l'autonomie est correcte - La condition de mise à jour d'un label prend en compte le coût ET l'autonomie restante (à coût égal, plus d'autonomie c'est mieux) - - Aux nœuds d'autoroute, on offre la possibilité de "recharger", ce qui crée une nouvelle option (un nouveau label avec batterie pleine et coût de recharge - ajouté) pour ce même nœud, à insérer dans le tas. - - -} - -normalement juste faut faire le verif de newcost avec l'autonomie - -avoir une option chemin impossible (trop éloigné des stations de recharges) - - -gérer le problème de la recharge, quand la faire ? - -*/ - - package org.insa.graphs.algorithm.shortestpath; import java.util.ArrayList; @@ -200,54 +104,50 @@ public class ProblemeOuvert extends DijkstraAlgorithm { 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); - - - 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); - succLabel.setAutonomieRestante(newBatteryLeft); - predecessorArcs[succ.getId()] = arc; - - // Insertion dans le tas car on est sûr qu'il n'est pas - - heap.insert(succLabel); - - notifyNodeReached(succ); - } - - // 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) { - if (newCost < succLabel.getCoutRealise()) { + if (batteryLeft < arcCost) { //si nous n'avons pas assez de batterie pour l'arc + // Recharge possible uniquement sur autoroute + if (arc.getRoadInformation().getType() == RoadType.MOTORWAY) { + double rechargeCost = newCost + 120; // 2 minutes de recharge + if (rechargeCost < 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); - succLabel.setAutonomieRestante(MAX_BATTERY); - predecessorArcs[succ.getId()] = arc; - - // Insertion dans le tas car on est sûr qu'il n'est pas - - heap.insert(succLabel); - - notifyNodeReached(succ); } + succLabel.setCoutRealise(rechargeCost); + succLabel.setPere(arc); + succLabel.setAutonomieRestante(MAX_BATTERY); + predecessorArcs[succ.getId()] = arc; + heap.insert(succLabel); + notifyNodeReached(succ); + } + } + } else { + // Assez de batterie + double newBatteryLeft = batteryLeft - arcCost; + if (newCost < succLabel.getCoutRealise()) { + if (succLabel.getCoutRealise() != Double.POSITIVE_INFINITY) { + heap.remove(succLabel); + } + succLabel.setCoutRealise(newCost); + succLabel.setPere(arc); + succLabel.setAutonomieRestante(newBatteryLeft); + predecessorArcs[succ.getId()] = arc; + heap.insert(succLabel); + notifyNodeReached(succ); + } } - } + + + + + } + + + + } + // Construction de la solution if (predecessorArcs[data.getDestination().getId()] == null) { @@ -270,4 +170,66 @@ public class ProblemeOuvert extends DijkstraAlgorithm { } + /*LabelProblemeOuvert tempLabel1=createLabel(succ); + LabelProblemeOuvert tempLabel2=createLabel(succ); + tempLabel1.setPere(succLabel.getPere()); + //tempLabel.setMarque(succLabel.getMarque()); + tempLabel1.setSommetCourant(succLabel.getSommetCourant()); + tempLabel1.setCoutRealise(succLabel.getCoutRealise()); + + tempLabel2.setPere(succLabel.getPere()); + //tempLabel.setMarque(succLabel.getMarque()); + tempLabel2.setSommetCourant(succLabel.getSommetCourant()); + tempLabel2.setCoutRealise(succLabel.getCoutRealise()); + + if (batteryLeft < arcCost) {// pas assez d'autnomie pour faire cet arc + // 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) { + if (newCost < tempLabel1.getCoutRealise()+120) { //on a rechargé, on rajoute 2mn (120 secondes) + tempLabel1.setCoutRealise(newCost); + tempLabel1.setPere(arc); + tempLabel1.setAutonomieRestante(MAX_BATTERY); + } + } + }else { // on a assez de batterie + + 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); + if (newCost < tempLabel2.getCoutRealise()) { + tempLabel2.setCoutRealise(newCost); + tempLabel2.setPere(arc); + tempLabel2.setAutonomieRestante(newBatteryLeft); + } + } + + int num_meilleur=0; + if (succLabel.getCoutRealise()>tempLabel1.getCoutRealise() && succLabel.getCoutRealise()>tempLabel2.getCoutRealise()){ + num_meilleur=1; + }else if (tempLabel1.getCoutRealise()>succLabel.getCoutRealise() && tempLabel1.getCoutRealise()>succLabel.getCoutRealise()){ + num_meilleur=2; + }else{ + num_meilleur=3; + } + + predecessorArcs[succ.getId()] = arc; + + if (num_meilleur==1){ + //on est bon succLabel est le meilleur + }else { + if (succLabel.getCoutRealise() != Double.POSITIVE_INFINITY){ + heap.remove(succLabel); + }else { + if (num_meilleur==2){ + heap.insert(tempLabel1); + labels[succ.getId()]=tempLabel1; + }else{ + heap.insert(tempLabel2); + labels[succ.getId()]=tempLabel2; + } + notifyNodeReached(succ); + } + }*/ diff --git a/be-graphes-gui/src/test/java/TestDijkstra.java b/be-graphes-gui/src/test/java/TestDijkstra.java index f4ee62d..cc746f4 100644 --- a/be-graphes-gui/src/test/java/TestDijkstra.java +++ b/be-graphes-gui/src/test/java/TestDijkstra.java @@ -198,10 +198,17 @@ public class TestDijkstra { //System.out.println("== Test bug dijkstra temps =="); // testScenario("paris.mapgr", 27361, 36108, Mode.TIME, true,0,false); //ce chemin visualisait un bug d'arrondi de dijkstra qui est corrigé actuellement // System.out.println("== Trajet impossible (piste cyclable) =="); - // testScenario("insa.mapgr",90,922 , Mode.LENGTH, false,false,true); //marche pas + // testScenario("insa.mapgr",90,922 , Mode.LENGTH, false,false,true); //marche pas //test probleme ouvert System.out.println("== Test Probleme Ouvert =="); - testScenario("toulouse.mapgr",33056,16303 , Mode.LENGTH, false,2,false); + testScenario("toulouse.mapgr",33056,16303 , Mode.TIME, false,2,false); + + //test probleme ouvert + System.out.println("== Test Probleme Ouvert =="); + testScenario("bretagne.mapgr",165317,74644 , Mode.TIME, false,2,false); + + //System.out.println("== Test Probleme Ouvert =="); + //testScenario("bretagne.mapgr",165317,74644 , Mode.TIME, false,2,false); } } diff --git a/problemeOuvert.odt b/problemeOuvert.odt index 82c39e3..48ab738 100644 Binary files a/problemeOuvert.odt and b/problemeOuvert.odt differ diff --git a/probleme_ouvert_voiture_elec.odt b/probleme_ouvert_voiture_elec.odt index 72544fc..0126f3c 100644 Binary files a/probleme_ouvert_voiture_elec.odt and b/probleme_ouvert_voiture_elec.odt differ