SUMO - Simulation of Urban MObility

TraCIDijkstraRouter.h

Go to the documentation of this file.
00001 /****************************************************************************/
00010 /****************************************************************************/
00011 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00012 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00013 /****************************************************************************/
00014 //
00015 //   This file is part of SUMO.
00016 //   SUMO is free software: you can redistribute it and/or modify
00017 //   it under the terms of the GNU General Public License as published by
00018 //   the Free Software Foundation, either version 3 of the License, or
00019 //   (at your option) any later version.
00020 //
00021 /****************************************************************************/
00022 #ifndef TRACIDIJKSTRAROUTER_H
00023 #define TRACIDIJKSTRAROUTER_H
00024 
00025 
00026 // ===========================================================================
00027 // included modules
00028 // ===========================================================================
00029 #ifdef _MSC_VER
00030 #include <windows_config.h>
00031 #else
00032 #include <config.h>
00033 #endif
00034 
00035 #ifndef NO_TRACI
00036 
00037 #include "utils/common/DijkstraRouterTT.h"
00038 #include <microsim/MSLane.h>
00039 #include <microsim/MSEdgeWeightsStorage.h>
00040 
00041 
00042 // ===========================================================================
00043 // class definitions
00044 // ===========================================================================
00061 template<class E>
00062 class TraCIDijkstraRouter : public SUMOAbstractRouter<E, MSVehicle> {
00063 public:
00065     TraCIDijkstraRouter(size_t noE/*, bool unbuildIsWarningOnly*/)
00066         : myNoE(noE), myReusableEdgeLists(true), myReusableEdgeInfoLists(true) { }
00067 
00069     virtual ~TraCIDijkstraRouter() { }
00070 
00076     class EdgeInfo {
00077     public:
00079         EdgeInfo()
00080             : edge(0), effort(0), prev(0) {}
00081 
00082 
00084         EdgeInfo(const E* edgeArg, SUMOReal effortArg, EdgeInfo* prevArg)
00085             : edge(edgeArg), effort(effortArg), prev(prevArg) {}
00086 
00088         EdgeInfo(const E* edgeArg, SUMOReal effortArg, EdgeInfo* prevArg, SUMOReal distArg)
00089             : edge(edgeArg), effort(effortArg), prev(prevArg), dist(distArg) {}
00090 
00092         const E* edge;
00093 
00095         SUMOReal effort;
00096 
00098         EdgeInfo* prev;
00099 
00101         SUMOReal dist;
00102 
00103     };
00104 
00109     class EdgeInfoByEffortComperator {
00110     public:
00112         explicit EdgeInfoByEffortComperator() { }
00113 
00115         ~EdgeInfoByEffortComperator() { }
00116 
00118         bool operator()(EdgeInfo* nod1, EdgeInfo* nod2) const {
00119             return nod1->effort > nod2->effort;
00120         }
00121     };
00122 
00123     virtual SUMOReal getEffort(const E* const e, SUMOReal t) const {
00124         SUMOReal value;
00125         if (MSNet::getInstance()->getWeightsStorage().retrieveExistingEffort(e, 0, t, value)) {
00126             return value;
00127         }
00128         const MSLane* const l = e->getLanes()[0];
00129         return l->getLength() / l->getMaxSpeed();
00130     }
00131 
00132 
00135     virtual void compute(const E* from, const E* to, const MSVehicle* const vehicle,
00136                          SUMOTime msTime, std::vector<const E*> &into) {
00137         UNUSED_PARAMETER(vehicle);
00138         const SUMOReal time = STEPS2TIME(msTime);
00139         // get structures to reuse
00140         std::vector<bool> *visited = myReusableEdgeLists.getFreeInstance();
00141         if (visited == 0) {
00142             visited = new std::vector<bool>(myNoE, false);
00143         } else {
00144             for (size_t i = 0; i < myNoE; i++) {
00145                 (*visited)[i] = false; // too slow? !!!
00146             }
00147         }
00148         EdgeInfoCont* storage = myReusableEdgeInfoLists.getFreeInstance();
00149         if (storage == 0) {
00150             storage = new EdgeInfoCont(myNoE);
00151         }
00152         storage->reset();
00153 
00154         // check the nodes
00155         if (from == 0 || to == 0) {
00156             throw std::exception();
00157         }
00158 
00159         // begin computation
00160         std::priority_queue < EdgeInfo*,
00161             std::vector<EdgeInfo*>,
00162             EdgeInfoByEffortComperator > frontierList;
00163         // add begin node
00164         const E* actualKnot = from;
00165         if (from != 0) {
00166             EdgeInfo* ei = storage->add(actualKnot, 0, 0);
00167             frontierList.push(ei);
00168         }
00169         bool isFirstIteration = true;
00170 
00171         // loop
00172         while (!frontierList.empty()) {
00173             // use the node with the minimal length
00174             EdgeInfo* minimumKnot = frontierList.top();
00175             const E* minEdge = minimumKnot->edge;
00176             frontierList.pop();
00177             // check whether the destination node was already reached
00178             if ((minEdge == to) && (!isFirstIteration)) {
00179                 buildPathFrom(minimumKnot, into);
00180                 clearTemporaryStorages(visited, storage);
00181                 return;
00182             }
00183             (*visited)[minEdge->getNumericalID()] = true;
00184             const SUMOReal effort = (SUMOReal)(minimumKnot->effort + getEffort(minEdge, time + minimumKnot->effort));
00185             // check all ways from the node with the minimal length
00186             unsigned int i = 0;
00187             const unsigned int length_size = minEdge->getNoFollowing();
00188             for (i = 0; i < length_size; i++) {
00189                 const E* help = minEdge->getFollower(i);
00190 
00191                 if ((!(*visited)[help->getNumericalID()] && effort < storage->getEffort(help))
00192                         || (help == to)) {
00193 //                    if (help!=from) {
00194                     frontierList.push(storage->add(help, effort, minimumKnot));
00195 //                    }
00196                 }
00197             }
00198 
00199             isFirstIteration = false;
00200         }
00201         clearTemporaryStorages(visited, storage);
00202     }
00203 
00204 
00205     SUMOReal recomputeCosts(const std::vector<const E*> &edges, const MSVehicle* const v, SUMOTime msTime) const {
00206         UNUSED_PARAMETER(v);
00207         const SUMOReal time = STEPS2TIME(msTime);
00208         SUMOReal costs = 0;
00209         for (typename std::vector<const E*>::const_iterator i = edges.begin(); i != edges.end(); i++) {
00210             costs += getEffort(*i, time + costs);
00211         }
00212         return costs;
00213     }
00214 
00215 public:
00217     void buildPathFrom(EdgeInfo* rbegin, std::vector<const E*> &edges) {
00218         std::deque<const E*> tmp;
00219         EdgeInfo* last = rbegin;
00220         while (rbegin != 0) {
00221             tmp.push_front((E*) rbegin->edge);  // !!!
00222             rbegin = rbegin->prev;
00223             if (rbegin == last) {
00224                 tmp.push_front((E*) rbegin->edge);
00225                 break;
00226             }
00227         }
00228         std::copy(tmp.begin(), tmp.end(), std::back_inserter(edges));
00229     }
00230 
00231 public:
00239     class EdgeInfoCont {
00240     public:
00242         EdgeInfoCont(size_t toAlloc)
00243             : myEdgeInfos(toAlloc + 1, EdgeInfo()) { }
00244 
00246         ~EdgeInfoCont() { }
00247 
00249         EdgeInfo* add(const E* edgeArg, SUMOReal effortArg, EdgeInfo* prevArg) {
00250             EdgeInfo* ret = &(myEdgeInfos[edgeArg->getNumericalID()]);
00251             ret->edge = edgeArg; // !!! may be set within the constructor
00252             ret->effort = effortArg;
00253             ret->prev = prevArg;
00254             ret->dist = 0;
00255             return ret;
00256         }
00257 
00259         EdgeInfo* add(const E* edgeArg, SUMOReal effortArg, EdgeInfo* prevArg,
00260                       SUMOReal distArg) {
00261             EdgeInfo* ret = &(myEdgeInfos[edgeArg->getNumericalID()]);
00262             ret->edge = edgeArg; // !!! may be set within the constructor
00263             ret->effort = effortArg;
00264             ret->prev = prevArg;
00265             ret->dist = distArg;
00266             return ret;
00267         }
00268 
00270         void reset() {
00271             for (typename std::vector<EdgeInfo>::iterator i = myEdgeInfos.begin(); i != myEdgeInfos.end(); i++) {
00272                 (*i).effort = std::numeric_limits<SUMOReal>::max();
00273             }
00274         }
00275 
00276 
00279         SUMOReal getEffort(const E* to) const {
00280             return myEdgeInfos[to->getNumericalID()].effort;
00281         }
00282 
00283     private:
00285         std::vector<EdgeInfo> myEdgeInfos;
00286 
00287     };
00288 
00289 protected:
00291     void clearTemporaryStorages(std::vector<bool> *edgeList,
00292                                 EdgeInfoCont* consecutionList) {
00293         myReusableEdgeLists.addFreeInstance(edgeList);
00294         myReusableEdgeInfoLists.addFreeInstance(consecutionList);
00295     }
00296 
00297 
00298 protected:
00300     size_t myNoE;
00301 
00303     InstancePool<std::vector<bool> > myReusableEdgeLists;
00304 
00306     InstancePool<EdgeInfoCont> myReusableEdgeInfoLists;
00307 };
00308 
00309 #endif
00310 
00311 #endif
00312 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines