SUMO - Simulation of Urban MObility

DijkstraRouterEffort.h

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // Dijkstra shortest path algorithm using other values
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 DijkstraRouterEffort_h
00020 #define DijkstraRouterEffort_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 #include <string>
00033 #include <functional>
00034 #include <vector>
00035 #include <set>
00036 #include <limits>
00037 #include <algorithm>
00038 #include <utils/common/InstancePool.h>
00039 #include <utils/common/MsgHandler.h>
00040 #include <utils/common/StdDefs.h>
00041 #include "SUMOAbstractRouter.h"
00042 
00043 
00044 // ===========================================================================
00045 // class definitions
00046 // ===========================================================================
00062 template<class E, class V, class PF>
00063 class DijkstraRouterEffortBase : public SUMOAbstractRouter<E, V>, public PF {
00064 public:
00066     DijkstraRouterEffortBase(size_t noE, bool unbuildIsWarning) :
00067         myErrorMsgHandler(unbuildIsWarning ?  MsgHandler::getWarningInstance() : MsgHandler::getErrorInstance()) {
00068         for (size_t i = 0; i < noE; i++) {
00069             myEdgeInfos.push_back(EdgeInfo(i));
00070         }
00071     }
00072 
00074     virtual ~DijkstraRouterEffortBase() { }
00075 
00081     class EdgeInfo {
00082     public:
00084         EdgeInfo() : edge(0), effort(0), leaveTime(0), prev(0), visited(false) {}
00085 
00087         EdgeInfo(size_t id)
00088             : edge(E::dictionary(id)), effort(0), leaveTime(0), prev(0), visited(false) {}
00089 
00091         const E* edge;
00092 
00094         SUMOReal effort;
00095 
00097         SUMOReal leaveTime;
00098 
00100         EdgeInfo* prev;
00101 
00103         bool visited;
00104 
00105     };
00106 
00111     class EdgeInfoByEffortComparator {
00112     public:
00114         bool operator()(EdgeInfo* nod1, EdgeInfo* nod2) const {
00115             if (nod1->effort == nod2->effort) {
00116                 return nod1->edge->getNumericalID() > nod2->edge->getNumericalID();
00117             }
00118             return nod1->effort>nod2->effort;
00119         }
00120     };
00121 
00122     virtual SUMOReal getEffort(const E* const e, const V* const v, SUMOReal t) = 0;
00123     virtual SUMOReal getTravelTime(const E* const e, const V* const v, SUMOReal t) = 0;
00124 
00125 
00128     virtual void compute(const E* from, const E* to, const V* const vehicle,
00129                          SUMOTime msTime, std::vector<const E*> &into) {
00130 
00131         SUMOReal time = (SUMOReal) msTime / 1000.;
00132         for (typename std::vector<EdgeInfo>::iterator i=myEdgeInfos.begin(); i!=myEdgeInfos.end(); i++) {
00133             (*i).effort = std::numeric_limits<SUMOReal>::max();
00134             (*i).visited = false;
00135         }
00136         assert(from!=0&&to!=0);
00137         myFrontierList.clear();
00138         // add begin node
00139         EdgeInfo* const fromInfo = &(myEdgeInfos[from->getNumericalID()]);
00140         fromInfo->effort = 0;
00141         fromInfo->prev = 0;
00142         fromInfo->leaveTime = (SUMOReal) time;
00143         myFrontierList.push_back(fromInfo);
00144         // loop
00145         while (!myFrontierList.empty()) {
00146             // use the node with the minimal length
00147             EdgeInfo* const minimumInfo = myFrontierList.front();
00148             const E* const minEdge = minimumInfo->edge;
00149             pop_heap(myFrontierList.begin(), myFrontierList.end(), myComparator);
00150             myFrontierList.pop_back();
00151             // check whether the destination node was already reached
00152             if (minEdge == to) {
00153                 buildPathFrom(minimumInfo, into);
00154                 return;
00155             }
00156             minimumInfo->visited = true;
00157             const SUMOReal effort = minimumInfo->effort + getEffort(minEdge, vehicle, (SUMOTime) minimumInfo->leaveTime);
00158             const SUMOReal leaveTime = minimumInfo->leaveTime + getTravelTime(minEdge, vehicle, (SUMOTime)minimumInfo->leaveTime);
00159             // check all ways from the node with the minimal length
00160             unsigned int i = 0;
00161             unsigned int length_size = minEdge->getNoFollowing();
00162             for (i=0; i<length_size; i++) {
00163                 const E* const follower = minEdge->getFollower(i);
00164                 EdgeInfo* const followerInfo = &(myEdgeInfos[follower->getNumericalID()]);
00165                 // check whether it can be used
00166                 if (PF::operator()(follower, vehicle)) {
00167                     continue;
00168                 }
00169                 const SUMOReal oldEffort = followerInfo->effort;
00170                 if (!followerInfo->visited && effort < oldEffort) {
00171                     followerInfo->effort = effort;
00172                     followerInfo->leaveTime = leaveTime;
00173                     followerInfo->prev = minimumInfo;
00174                     if (oldEffort == std::numeric_limits<SUMOReal>::max()) {
00175                         myFrontierList.push_back(followerInfo);
00176                         push_heap(myFrontierList.begin(), myFrontierList.end(), myComparator);
00177                     } else {
00178                         push_heap(myFrontierList.begin(),
00179                                   find(myFrontierList.begin(), myFrontierList.end(), followerInfo) + 1,
00180                                   myComparator);
00181                     }
00182                 }
00183             }
00184         }
00185         myErrorMsgHandler->inform("No connection between '" + from->getID() + "' and '" + to->getID() + "' found.");
00186     }
00187 
00188 
00189     SUMOReal recomputeCosts(const std::vector<const E*> &edges, const V* const v, SUMOTime msTime) throw() {
00190         SUMOReal time = (SUMOReal) msTime / 1000.;
00191         SUMOReal costs = 0;
00192         SUMOReal t = (SUMOReal) time;
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, (SUMOTime) t);
00198             t += getTravelTime(*i, v, (SUMOTime) 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) {
00240         return (myReceiver->*myEffortOperation)(e, v, t);
00241     }
00242 
00243     inline SUMOReal getTravelTime(const E* const e, const V* const v, SUMOReal t) {
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) {
00271         return (e->*myEffortOperation)(v, t);
00272     }
00273 
00274     inline SUMOReal getTravelTime(const E* const e, const V* const v, SUMOReal t) {
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