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 2001-2010 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 unbuildIsWarningOnly)
00067             : myUnbuildIsWarningOnly(unbuildIsWarningOnly) {
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) {}
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         EdgeInfo *prev;
00098 
00100         SUMOReal leaveTime;
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         if (!myUnbuildIsWarningOnly) {
00186             MsgHandler::getErrorInstance()->inform("No connection between '" + from->getID() + "' and '" + to->getID() + "' found.");
00187         } else {
00188             WRITE_WARNING("No connection between '" + from->getID() + "' and '" + to->getID() + "' found.");
00189         }
00190     }
00191 
00192 
00193     SUMOReal recomputeCosts(const std::vector<const E*> &edges, const V * const v, SUMOTime msTime) throw() {
00194         SUMOReal time = (SUMOReal) msTime / 1000.;
00195         SUMOReal costs = 0;
00196         SUMOReal t = (SUMOReal) time;
00197         for (typename std::vector<const E*>::const_iterator i=edges.begin(); i!=edges.end(); ++i) {
00198             if (PF::operator()(*i, v)) {
00199                 return -1;
00200             }
00201             costs += getEffort(*i, v, (SUMOTime) t);
00202             t += getTravelTime(*i, v, (SUMOTime) t);
00203         }
00204         return costs;
00205     }
00206 
00207 public:
00209     void buildPathFrom(EdgeInfo *rbegin, std::vector<const E *> &edges) {
00210         std::deque<const E*> tmp;
00211         while (rbegin!=0) {
00212             tmp.push_front((E *) rbegin->edge); // !!!
00213             rbegin = rbegin->prev;
00214         }
00215         std::copy(tmp.begin(), tmp.end(), std::back_inserter(edges));
00216     }
00217 
00218 protected:
00220     std::vector<EdgeInfo> myEdgeInfos;
00221 
00223     std::vector<EdgeInfo*> myFrontierList;
00224 
00225     EdgeInfoByEffortComparator myComparator;
00226 
00227     bool myUnbuildIsWarningOnly;
00228 
00229 };
00230 
00231 
00232 template<class E, class V, class PF, class EC>
00233 class DijkstraRouterEffort_ByProxi : public DijkstraRouterEffortBase<E, V, PF> {
00234 public:
00236     typedef SUMOReal(EC::* Operation)(const E * const, const V * const, SUMOReal) const;
00237 
00238     DijkstraRouterEffort_ByProxi(size_t noE, bool unbuildIsWarningOnly, EC* receiver, Operation effortOperation, Operation ttOperation)
00239             : DijkstraRouterEffortBase<E, V, PF>(noE, unbuildIsWarningOnly),
00240             myReceiver(receiver), myEffortOperation(effortOperation), myTTOperation(ttOperation) {}
00241 
00242     inline SUMOReal getEffort(const E * const e, const V * const v, SUMOReal t) {
00243         return (myReceiver->*myEffortOperation)(e, v, t);
00244     }
00245 
00246     inline SUMOReal getTravelTime(const E * const e, const V * const v, SUMOReal t) {
00247         return (myReceiver->*myTTOperation)(e, v, t);
00248     }
00249 
00250 private:
00252     EC* myReceiver;
00253 
00255     Operation myEffortOperation;
00256 
00258     Operation myTTOperation;
00259 
00260 };
00261 
00262 
00263 template<class E, class V, class PF>
00264 class DijkstraRouterEffort_Direct : public DijkstraRouterEffortBase<E, V, PF> {
00265 public:
00267     typedef SUMOReal(E::* Operation)(const V * const, SUMOReal) const;
00268 
00269     DijkstraRouterEffort_Direct(size_t noE, bool unbuildIsWarningOnly, Operation effortOperation, Operation ttOperation)
00270             : DijkstraRouterEffortBase<E, V, PF>(noE, unbuildIsWarningOnly),
00271             myEffortOperation(effortOperation), myTTOperation(ttOperation) {}
00272 
00273     inline SUMOReal getEffort(const E * const e, const V * const v, SUMOReal t) {
00274         return (e->*myEffortOperation)(v, t);
00275     }
00276 
00277     inline SUMOReal getTravelTime(const E * const e, const V * const v, SUMOReal t) {
00278         return (e->*myTTOperation)(v, t);
00279     }
00280 
00281 private:
00283     Operation myEffortOperation;
00284 
00286     Operation myTTOperation;
00287 
00288 
00289 };
00290 
00291 
00292 #endif
00293 
00294 /****************************************************************************/
00295 

Generated on Wed May 5 00:06:28 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6