SUMO - Simulation of Urban MObility

DijkstraRouterEffort.h

Go to the documentation of this file.
00001 /****************************************************************************/
00009 // Dijkstra shortest path algorithm using other values
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 DijkstraRouterEffort_h
00023 #define DijkstraRouterEffort_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 <utils/common/InstancePool.h>
00042 #include <utils/common/MsgHandler.h>
00043 #include <utils/common/StdDefs.h>
00044 #include "SUMOAbstractRouter.h"
00045 
00046 
00047 // ===========================================================================
00048 // class definitions
00049 // ===========================================================================
00065 template<class E, class V, class PF>
00066 class DijkstraRouterEffortBase : public SUMOAbstractRouter<E, V>, public PF {
00067 public:
00069     DijkstraRouterEffortBase(size_t noE, bool unbuildIsWarning) :
00070         myErrorMsgHandler(unbuildIsWarning ?  MsgHandler::getWarningInstance() : MsgHandler::getErrorInstance()) {
00071         for (size_t i = 0; i < noE; i++) {
00072             myEdgeInfos.push_back(EdgeInfo(i));
00073         }
00074     }
00075 
00077     virtual ~DijkstraRouterEffortBase() { }
00078 
00084     class EdgeInfo {
00085     public:
00087         EdgeInfo() : edge(0), effort(0), leaveTime(0), prev(0), visited(false) {}
00088 
00090         EdgeInfo(size_t id)
00091             : edge(E::dictionary(id)), effort(0), leaveTime(0), prev(0), visited(false) {}
00092 
00094         const E* edge;
00095 
00097         SUMOReal effort;
00098 
00100         SUMOReal leaveTime;
00101 
00103         EdgeInfo* prev;
00104 
00106         bool visited;
00107 
00108     };
00109 
00114     class EdgeInfoByEffortComparator {
00115     public:
00117         bool operator()(EdgeInfo* nod1, EdgeInfo* nod2) const {
00118             if (nod1->effort == nod2->effort) {
00119                 return nod1->edge->getNumericalID() > nod2->edge->getNumericalID();
00120             }
00121             return nod1->effort > nod2->effort;
00122         }
00123     };
00124 
00125     virtual SUMOReal getEffort(const E* const e, const V* const v, SUMOReal t) const = 0;
00126     virtual SUMOReal getTravelTime(const E* const e, const V* const v, SUMOReal t) const = 0;
00127 
00128 
00131     virtual void compute(const E* from, const E* to, const V* const vehicle,
00132                          SUMOTime msTime, std::vector<const E*> &into) {
00133         for (typename std::vector<EdgeInfo>::iterator i = myEdgeInfos.begin(); i != myEdgeInfos.end(); i++) {
00134             (*i).effort = std::numeric_limits<SUMOReal>::max();
00135             (*i).visited = false;
00136         }
00137         assert(from != 0 && to != 0);
00138         myFrontierList.clear();
00139         // add begin node
00140         EdgeInfo* const fromInfo = &(myEdgeInfos[from->getNumericalID()]);
00141         fromInfo->effort = 0;
00142         fromInfo->prev = 0;
00143         fromInfo->leaveTime = STEPS2TIME(msTime);
00144         myFrontierList.push_back(fromInfo);
00145         // loop
00146         while (!myFrontierList.empty()) {
00147             // use the node with the minimal length
00148             EdgeInfo* const minimumInfo = myFrontierList.front();
00149             const E* const minEdge = minimumInfo->edge;
00150             pop_heap(myFrontierList.begin(), myFrontierList.end(), myComparator);
00151             myFrontierList.pop_back();
00152             // check whether the destination node was already reached
00153             if (minEdge == to) {
00154                 buildPathFrom(minimumInfo, into);
00155                 return;
00156             }
00157             minimumInfo->visited = true;
00158             const SUMOReal effort = minimumInfo->effort + getEffort(minEdge, vehicle, minimumInfo->leaveTime);
00159             const SUMOReal leaveTime = minimumInfo->leaveTime + getTravelTime(minEdge, vehicle, minimumInfo->leaveTime);
00160             // check all ways from the node with the minimal length
00161             unsigned int i = 0;
00162             const unsigned int length_size = minEdge->getNoFollowing();
00163             for (i = 0; i < length_size; i++) {
00164                 const E* const follower = minEdge->getFollower(i);
00165                 EdgeInfo* const followerInfo = &(myEdgeInfos[follower->getNumericalID()]);
00166                 // check whether it can be used
00167                 if (PF::operator()(follower, vehicle)) {
00168                     continue;
00169                 }
00170                 const SUMOReal oldEffort = followerInfo->effort;
00171                 if (!followerInfo->visited && effort < oldEffort) {
00172                     followerInfo->effort = effort;
00173                     followerInfo->leaveTime = leaveTime;
00174                     followerInfo->prev = minimumInfo;
00175                     if (oldEffort == std::numeric_limits<SUMOReal>::max()) {
00176                         myFrontierList.push_back(followerInfo);
00177                         push_heap(myFrontierList.begin(), myFrontierList.end(), myComparator);
00178                     } else {
00179                         push_heap(myFrontierList.begin(),
00180                                   find(myFrontierList.begin(), myFrontierList.end(), followerInfo) + 1,
00181                                   myComparator);
00182                     }
00183                 }
00184             }
00185         }
00186         myErrorMsgHandler->inform("No connection between '" + from->getID() + "' and '" + to->getID() + "' found.");
00187     }
00188 
00189 
00190     SUMOReal recomputeCosts(const std::vector<const E*> &edges, const V* const v, SUMOTime msTime) const {
00191         SUMOReal costs = 0;
00192         SUMOReal t = STEPS2TIME(msTime);
00193         for (typename std::vector<const E*>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
00194             if (PF::operator()(*i, v)) {
00195                 return -1;
00196             }
00197             costs += getEffort(*i, v, t);
00198             t += getTravelTime(*i, v, t);
00199         }
00200         return costs;
00201     }
00202 
00203 public:
00205     void buildPathFrom(EdgeInfo* rbegin, std::vector<const E*> &edges) {
00206         std::deque<const E*> tmp;
00207         while (rbegin != 0) {
00208             tmp.push_front((E*) rbegin->edge);  // !!!
00209             rbegin = rbegin->prev;
00210         }
00211         std::copy(tmp.begin(), tmp.end(), std::back_inserter(edges));
00212     }
00213 
00214 protected:
00216     std::vector<EdgeInfo> myEdgeInfos;
00217 
00219     std::vector<EdgeInfo*> myFrontierList;
00220 
00221     EdgeInfoByEffortComparator myComparator;
00222 
00224     MsgHandler* const myErrorMsgHandler;
00225 
00226 };
00227 
00228 
00229 template<class E, class V, class PF, class EC>
00230 class DijkstraRouterEffort_ByProxi : public DijkstraRouterEffortBase<E, V, PF> {
00231 public:
00233     typedef SUMOReal(EC::* Operation)(const E* const, const V* const, SUMOReal) const;
00234 
00235     DijkstraRouterEffort_ByProxi(size_t noE, bool unbuildIsWarningOnly, EC* receiver, Operation effortOperation, Operation ttOperation)
00236         : DijkstraRouterEffortBase<E, V, PF>(noE, unbuildIsWarningOnly),
00237           myReceiver(receiver), myEffortOperation(effortOperation), myTTOperation(ttOperation) {}
00238 
00239     inline SUMOReal getEffort(const E* const e, const V* const v, SUMOReal t) const {
00240         return (myReceiver->*myEffortOperation)(e, v, t);
00241     }
00242 
00243     inline SUMOReal getTravelTime(const E* const e, const V* const v, SUMOReal t) const {
00244         return (myReceiver->*myTTOperation)(e, v, t);
00245     }
00246 
00247 private:
00249     EC* myReceiver;
00250 
00252     Operation myEffortOperation;
00253 
00255     Operation myTTOperation;
00256 
00257 };
00258 
00259 
00260 template<class E, class V, class PF>
00261 class DijkstraRouterEffort_Direct : public DijkstraRouterEffortBase<E, V, PF> {
00262 public:
00264     typedef SUMOReal(E::* Operation)(const V* const, SUMOReal) const;
00265 
00266     DijkstraRouterEffort_Direct(size_t noE, bool unbuildIsWarningOnly, Operation effortOperation, Operation ttOperation)
00267         : DijkstraRouterEffortBase<E, V, PF>(noE, unbuildIsWarningOnly),
00268           myEffortOperation(effortOperation), myTTOperation(ttOperation) {}
00269 
00270     inline SUMOReal getEffort(const E* const e, const V* const v, SUMOReal t) const {
00271         return (e->*myEffortOperation)(v, t);
00272     }
00273 
00274     inline SUMOReal getTravelTime(const E* const e, const V* const v, SUMOReal t) const {
00275         return (e->*myTTOperation)(v, t);
00276     }
00277 
00278 private:
00280     Operation myEffortOperation;
00281 
00283     Operation myTTOperation;
00284 
00285 
00286 };
00287 
00288 
00289 #endif
00290 
00291 /****************************************************************************/
00292 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines