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