SUMO - Simulation of Urban MObility

DijkstraRouterTT.h

Go to the documentation of this file.
00001 /****************************************************************************/
00009 // Dijkstra shortest path algorithm using travel time
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 DijkstraRouterTT_h
00023 #define DijkstraRouterTT_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 #include <string>
00036 #include <functional>
00037 #include <vector>
00038 #include <set>
00039 #include <limits>
00040 #include <algorithm>
00041 #include <iterator>
00042 #include <utils/common/InstancePool.h>
00043 #include <utils/common/MsgHandler.h>
00044 #include <utils/common/StdDefs.h>
00045 #include "SUMOAbstractRouter.h"
00046 
00047 
00048 // ===========================================================================
00049 // class definitions
00050 // ===========================================================================
00066 template<class E, class V, class PF>
00067 class DijkstraRouterTTBase : public SUMOAbstractRouter<E, V>, public PF {
00068 public:
00070     DijkstraRouterTTBase(size_t noE, bool unbuildIsWarning) :
00071         myErrorMsgHandler(unbuildIsWarning ?  MsgHandler::getWarningInstance() : MsgHandler::getErrorInstance()) {
00072         for (size_t i = 0; i < noE; i++) {
00073             myEdgeInfos.push_back(EdgeInfo(i));
00074         }
00075     }
00076 
00078     virtual ~DijkstraRouterTTBase() { }
00079 
00085     class EdgeInfo {
00086     public:
00088         EdgeInfo(size_t id)
00089             : edge(E::dictionary(id)), traveltime(0), prev(0), visited(false) {}
00090 
00092         const E* edge;
00093 
00095         SUMOReal traveltime;
00096 
00098         EdgeInfo* prev;
00099 
00101         bool visited;
00102 
00103     };
00104 
00109     class EdgeInfoByTTComparator {
00110     public:
00112         bool operator()(const EdgeInfo* nod1, const EdgeInfo* nod2) const {
00113             if (nod1->traveltime == nod2->traveltime) {
00114                 return nod1->edge->getNumericalID() > nod2->edge->getNumericalID();
00115             }
00116             return nod1->traveltime > nod2->traveltime;
00117         }
00118     };
00119 
00120     virtual SUMOReal getEffort(const E* const e, const V* const v, SUMOReal t) const = 0;
00121 
00122 
00125     virtual void compute(const E* from, const E* to, const V* const vehicle,
00126                          SUMOTime msTime, std::vector<const E*> &into) {
00127         const SUMOReal time = STEPS2TIME(msTime);
00128         for (typename std::vector<EdgeInfo>::iterator i = myEdgeInfos.begin(); i != myEdgeInfos.end(); i++) {
00129             (*i).traveltime = std::numeric_limits<SUMOReal>::max();
00130             (*i).visited = false;
00131         }
00132         assert(from != 0 && to != 0);
00133         myFrontierList.clear();
00134         // add begin node
00135         EdgeInfo* const fromInfo = &(myEdgeInfos[from->getNumericalID()]);
00136         fromInfo->traveltime = 0;
00137         fromInfo->prev = 0;
00138         myFrontierList.push_back(fromInfo);
00139         // loop
00140         while (!myFrontierList.empty()) {
00141             // use the node with the minimal length
00142             EdgeInfo* const minimumInfo = myFrontierList.front();
00143             const E* const minEdge = minimumInfo->edge;
00144             pop_heap(myFrontierList.begin(), myFrontierList.end(), myComparator);
00145             myFrontierList.pop_back();
00146             // check whether the destination node was already reached
00147             if (minEdge == to) {
00148                 buildPathFrom(minimumInfo, into);
00149                 return;
00150             }
00151             minimumInfo->visited = true;
00152             const SUMOReal traveltime = minimumInfo->traveltime + getEffort(minEdge, vehicle, time + minimumInfo->traveltime);
00153             // check all ways from the node with the minimal length
00154             unsigned int i = 0;
00155             const unsigned int length_size = minEdge->getNoFollowing();
00156             for (i = 0; i < length_size; i++) {
00157                 const E* const follower = minEdge->getFollower(i);
00158                 EdgeInfo* const followerInfo = &(myEdgeInfos[follower->getNumericalID()]);
00159                 // check whether it can be used
00160                 if (PF::operator()(follower, vehicle)) {
00161                     continue;
00162                 }
00163                 const SUMOReal oldEffort = followerInfo->traveltime;
00164                 if (!followerInfo->visited && traveltime < oldEffort) {
00165                     followerInfo->traveltime = traveltime;
00166                     followerInfo->prev = minimumInfo;
00167                     if (oldEffort == std::numeric_limits<SUMOReal>::max()) {
00168                         myFrontierList.push_back(followerInfo);
00169                         push_heap(myFrontierList.begin(), myFrontierList.end(), myComparator);
00170                     } else {
00171                         push_heap(myFrontierList.begin(),
00172                                   find(myFrontierList.begin(), myFrontierList.end(), followerInfo) + 1,
00173                                   myComparator);
00174                     }
00175                 }
00176             }
00177         }
00178         myErrorMsgHandler->inform("No connection between '" + from->getID() + "' and '" + to->getID() + "' found.");
00179     }
00180 
00181 
00182     SUMOReal recomputeCosts(const std::vector<const E*> &edges, const V* const v, SUMOTime msTime) const {
00183         const SUMOReal time = STEPS2TIME(msTime);
00184         SUMOReal costs = 0;
00185         for (typename std::vector<const E*>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
00186             if (PF::operator()(*i, v)) {
00187                 return -1;
00188             }
00189             costs += getEffort(*i, v, time + costs);
00190         }
00191         return costs;
00192     }
00193 
00194 public:
00196     void buildPathFrom(EdgeInfo* rbegin, std::vector<const E*> &edges) {
00197         std::deque<const E*> tmp;
00198         while (rbegin != 0) {
00199             tmp.push_front((E*) rbegin->edge);  // !!!
00200             rbegin = rbegin->prev;
00201         }
00202         std::copy(tmp.begin(), tmp.end(), std::back_inserter(edges));
00203     }
00204 
00205 protected:
00207     std::vector<EdgeInfo> myEdgeInfos;
00208 
00210     std::vector<EdgeInfo*> myFrontierList;
00211 
00212     EdgeInfoByTTComparator myComparator;
00213 
00215     MsgHandler* const myErrorMsgHandler;
00216 
00217 };
00218 
00219 
00220 template<class E, class V, class PF, class EC>
00221 class DijkstraRouterTT_ByProxi : public DijkstraRouterTTBase<E, V, PF> {
00222 public:
00224     typedef SUMOReal(EC::* Operation)(const E* const, const V* const, SUMOReal) const;
00225 
00226     DijkstraRouterTT_ByProxi(size_t noE, bool unbuildIsWarningOnly, EC* receiver, Operation operation)
00227         : DijkstraRouterTTBase<E, V, PF>(noE, unbuildIsWarningOnly),
00228           myReceiver(receiver), myOperation(operation) {}
00229 
00230     inline SUMOReal getEffort(const E* const e, const V* const v, SUMOReal t) const {
00231         return (myReceiver->*myOperation)(e, v, t);
00232     }
00233 
00234 private:
00236     EC* myReceiver;
00237 
00239     Operation myOperation;
00240 
00241 
00242 };
00243 
00244 
00245 template<class E, class V, class PF>
00246 class DijkstraRouterTT_Direct : public DijkstraRouterTTBase<E, V, PF> {
00247 public:
00249     typedef SUMOReal(E::* Operation)(const V* const, SUMOReal) const;
00250 
00251     DijkstraRouterTT_Direct(size_t noE, bool unbuildIsWarningOnly, Operation operation)
00252         : DijkstraRouterTTBase<E, V, PF>(noE, unbuildIsWarningOnly), myOperation(operation) {}
00253 
00254     inline SUMOReal getEffort(const E* const e, const V* const v, SUMOReal t) const {
00255         return (e->*myOperation)(v, t);
00256     }
00257 
00258 private:
00259     Operation myOperation;
00260 
00261 };
00262 
00263 
00264 #endif
00265 
00266 /****************************************************************************/
00267 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines