SUMO - Simulation of Urban MObility

TraCIDijkstraRouter.h

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