|
SUMO - Simulation of Urban MObility
|
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