TraCIDijkstraRouter.h

Go to the documentation of this file.
00001 /****************************************************************************/
00008 /****************************************************************************/
00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00010 // Copyright 2001-2010 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         // get structures to reuse
00136         std::vector<bool> *visited = myReusableEdgeLists.getFreeInstance();
00137         if (visited==0) {
00138             visited = new std::vector<bool>(myNoE, false);
00139         } else {
00140             for (size_t i=0; i<myNoE; i++) {
00141                 (*visited)[i] = false; // too slow? !!!
00142             }
00143         }
00144         EdgeInfoCont *storage = myReusableEdgeInfoLists.getFreeInstance();
00145         if (storage==0) {
00146             storage = new EdgeInfoCont(myNoE);
00147         }
00148         storage->reset();
00149 
00150         // check the nodes
00151         if (from==0||to==0) {
00152             throw std::exception();
00153         }
00154 
00155         // begin computation
00156         std::priority_queue<EdgeInfo*,
00157         std::vector<EdgeInfo*>,
00158         EdgeInfoByEffortComperator> frontierList;
00159         // add begin node
00160         const E *actualKnot = from;
00161         if (from != 0) {
00162             EdgeInfo *ei = storage->add(actualKnot, 0, 0);
00163             frontierList.push(ei);
00164         }
00165         bool isFirstIteration = true;
00166 
00167         // loop
00168         while (!frontierList.empty()) {
00169             // use the node with the minimal length
00170             EdgeInfo *minimumKnot = frontierList.top();
00171             const E *minEdge = minimumKnot->edge;
00172             frontierList.pop();
00173             // check whether the destination node was already reached
00174             if ((minEdge == to) && (!isFirstIteration)) {
00175                 buildPathFrom(minimumKnot, into);
00176                 clearTemporaryStorages(visited, storage);
00177                 return;
00178             }
00179             (*visited)[minEdge->getNumericalID()] = true;
00180             SUMOReal effort = (SUMOReal)(minimumKnot->effort + getEffort(minEdge, time + minimumKnot->effort));
00181             // check all ways from the node with the minimal length
00182             unsigned int i = 0;
00183             unsigned int length_size = minEdge->getNoFollowing();
00184             for (i=0; i<length_size; i++) {
00185                 const E* help = minEdge->getFollower(i);
00186 
00187                 if ((!(*visited)[help->getNumericalID()] && effort < storage->getEffort(help))
00188                         || (help == to)) {
00189 //                    if (help!=from) {
00190                     frontierList.push(storage->add(help, effort, minimumKnot));
00191 //                    }
00192                 }
00193             }
00194 
00195             isFirstIteration = false;
00196         }
00197         clearTemporaryStorages(visited, storage);
00198     }
00199 
00200 
00201     SUMOReal recomputeCosts(const std::vector<const E*> &edges, const MSVehicle * const v, SUMOTime time) throw() {
00202         SUMOReal costs = 0;
00203         for (typename std::vector<const E*>::const_iterator i=edges.begin(); i!=edges.end(); i++) {
00204             costs += getEffort(*i, (SUMOTime)(time + costs));
00205         }
00206         return costs;
00207     }
00208 
00209 public:
00211     void buildPathFrom(EdgeInfo *rbegin, std::vector<const E *> &edges) {
00212         std::deque<const E*> tmp;
00213         EdgeInfo* last = rbegin;
00214         while (rbegin!=0) {
00215             tmp.push_front((E *) rbegin->edge); // !!!
00216             rbegin = rbegin->prev;
00217             if (rbegin == last) {
00218                 tmp.push_front((E *) rbegin->edge);
00219                 break;
00220             }
00221         }
00222         std::copy(tmp.begin(), tmp.end(), std::back_inserter(edges));
00223     }
00224 
00225 public:
00233     class EdgeInfoCont {
00234     public:
00236         EdgeInfoCont(size_t toAlloc)
00237                 : myEdgeInfos(toAlloc+1, EdgeInfo()) { }
00238 
00240         ~EdgeInfoCont() { }
00241 
00243         EdgeInfo *add(const E *edgeArg, SUMOReal effortArg, EdgeInfo *prevArg) {
00244             EdgeInfo *ret = &(myEdgeInfos[edgeArg->getNumericalID()]);
00245             ret->edge = edgeArg; // !!! may be set within the constructor
00246             ret->effort = effortArg;
00247             ret->prev = prevArg;
00248             ret->dist = 0;
00249             return ret;
00250         }
00251 
00253         EdgeInfo *add(const E *edgeArg, SUMOReal effortArg, EdgeInfo *prevArg,
00254                       SUMOReal distArg) {
00255             EdgeInfo *ret = &(myEdgeInfos[edgeArg->getNumericalID()]);
00256             ret->edge = edgeArg; // !!! may be set within the constructor
00257             ret->effort = effortArg;
00258             ret->prev = prevArg;
00259             ret->dist = distArg;
00260             return ret;
00261         }
00262 
00264         void reset() {
00265             for (typename std::vector<EdgeInfo>::iterator i=myEdgeInfos.begin(); i!=myEdgeInfos.end(); i++) {
00266                 (*i).effort = std::numeric_limits<SUMOReal>::max();
00267             }
00268         }
00269 
00270 
00273         SUMOReal getEffort(const E *to) const {
00274             return myEdgeInfos[to->getNumericalID()].effort;
00275         }
00276 
00277     private:
00279         std::vector<EdgeInfo> myEdgeInfos;
00280 
00281     };
00282 
00283 protected:
00285     void clearTemporaryStorages(std::vector<bool> *edgeList,
00286                                 EdgeInfoCont *consecutionList) {
00287         myReusableEdgeLists.addFreeInstance(edgeList);
00288         myReusableEdgeInfoLists.addFreeInstance(consecutionList);
00289     }
00290 
00291 
00292 protected:
00294     size_t myNoE;
00295 
00297     InstancePool<std::vector<bool> > myReusableEdgeLists;
00298 
00300     InstancePool<EdgeInfoCont> myReusableEdgeInfoLists;
00301 };
00302 
00303 #endif
00304 
00305 #endif
00306 

Generated on Wed May 5 00:06:37 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6