DijkstraRouterTT.h

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // Dijkstra shortest path algorithm using travel time
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 DijkstraRouterTT_h
00020 #define DijkstraRouterTT_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 DijkstraRouterTTBase : public SUMOAbstractRouter<E, V>, public PF {
00064 public:
00066     DijkstraRouterTTBase(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 ~DijkstraRouterTTBase() { }
00075 
00081     class EdgeInfo {
00082     public:
00084         EdgeInfo(size_t id)
00085                 : edge(E::dictionary(id)), traveltime(0), prev(0), visited(false) {}
00086 
00088         const E *edge;
00089 
00091         SUMOReal traveltime;
00092 
00094         EdgeInfo *prev;
00095 
00097         bool visited;
00098 
00099     };
00100 
00105     class EdgeInfoByTTComparator {
00106     public:
00108         bool operator()(const EdgeInfo *nod1, const EdgeInfo *nod2) const {
00109             if (nod1->traveltime == nod2->traveltime) {
00110                 return nod1->edge->getNumericalID() > nod2->edge->getNumericalID();
00111             }
00112             return nod1->traveltime>nod2->traveltime;
00113         }
00114     };
00115 
00116     virtual SUMOReal getEffort(const E * const e, const V * const v, SUMOReal t) = 0;
00117 
00118 
00121     virtual void compute(const E *from, const E *to, const V * const vehicle,
00122                          SUMOTime msTime, std::vector<const E*> &into) {
00123 
00124         SUMOReal time = (SUMOReal) msTime / 1000.;
00125         for (typename std::vector<EdgeInfo>::iterator i=myEdgeInfos.begin(); i!=myEdgeInfos.end(); i++) {
00126             (*i).traveltime = std::numeric_limits<SUMOReal>::max();
00127             (*i).visited = false;
00128         }
00129         assert(from!=0&&to!=0);
00130         myFrontierList.clear();
00131         // add begin node
00132         EdgeInfo* const fromInfo = &(myEdgeInfos[from->getNumericalID()]);
00133         fromInfo->traveltime = 0;
00134         fromInfo->prev = 0;
00135         myFrontierList.push_back(fromInfo);
00136         // loop
00137         while (!myFrontierList.empty()) {
00138             // use the node with the minimal length
00139             EdgeInfo * const minimumInfo = myFrontierList.front();
00140             const E * const minEdge = minimumInfo->edge;
00141             pop_heap(myFrontierList.begin(), myFrontierList.end(), myComparator);
00142             myFrontierList.pop_back();
00143             // check whether the destination node was already reached
00144             if (minEdge == to) {
00145                 buildPathFrom(minimumInfo, into);
00146                 return;
00147             }
00148             minimumInfo->visited = true;
00149             const SUMOReal traveltime = minimumInfo->traveltime + getEffort(minEdge, vehicle, time + (SUMOTime)minimumInfo->traveltime);
00150             // check all ways from the node with the minimal length
00151             unsigned int i = 0;
00152             const unsigned int length_size = minEdge->getNoFollowing();
00153             for (i=0; i<length_size; i++) {
00154                 const E* const follower = minEdge->getFollower(i);
00155                 EdgeInfo* const followerInfo = &(myEdgeInfos[follower->getNumericalID()]);
00156                 // check whether it can be used
00157                 if (PF::operator()(follower, vehicle)) {
00158                     continue;
00159                 }
00160                 const SUMOReal oldEffort = followerInfo->traveltime;
00161                 if (!followerInfo->visited && traveltime < oldEffort) {
00162                     followerInfo->traveltime = traveltime;
00163                     followerInfo->prev = minimumInfo;
00164                     if (oldEffort == std::numeric_limits<SUMOReal>::max()) {
00165                         myFrontierList.push_back(followerInfo);
00166                         push_heap(myFrontierList.begin(), myFrontierList.end(), myComparator);
00167                     } else {
00168                         push_heap(myFrontierList.begin(),
00169                                   find(myFrontierList.begin(), myFrontierList.end(), followerInfo) + 1,
00170                                   myComparator);
00171                     }
00172                 }
00173             }
00174         }
00175         if (!myUnbuildIsWarningOnly) {
00176             MsgHandler::getErrorInstance()->inform("No connection between '" + from->getID() + "' and '" + to->getID() + "' found.");
00177         } else {
00178             WRITE_WARNING("No connection between '" + from->getID() + "' and '" + to->getID() + "' found.");
00179         }
00180     }
00181 
00182 
00183     SUMOReal recomputeCosts(const std::vector<const E*> &edges, const V * const v, SUMOTime msTime) throw() {
00184         SUMOReal time = (SUMOReal) msTime / 1000.;
00185         SUMOReal costs = 0;
00186         for (typename std::vector<const E*>::const_iterator i=edges.begin(); i!=edges.end(); ++i) {
00187             if (PF::operator()(*i, v)) {
00188                 return -1;
00189             }
00190             costs += getEffort(*i, v, (SUMOTime)(time + costs));
00191         }
00192         return costs;
00193     }
00194 
00195 public:
00197     void buildPathFrom(EdgeInfo *rbegin, std::vector<const E *> &edges) {
00198         std::deque<const E*> tmp;
00199         while (rbegin!=0) {
00200             tmp.push_front((E *) rbegin->edge); // !!!
00201             rbegin = rbegin->prev;
00202         }
00203         std::copy(tmp.begin(), tmp.end(), std::back_inserter(edges));
00204     }
00205 
00206 protected:
00208     std::vector<EdgeInfo> myEdgeInfos;
00209 
00211     std::vector<EdgeInfo*> myFrontierList;
00212 
00213     EdgeInfoByTTComparator myComparator;
00214 
00215     bool myUnbuildIsWarningOnly;
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) {
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) {
00255         return (e->*myOperation)(v, t);
00256     }
00257 
00258 private:
00259     Operation myOperation;
00260 
00261 };
00262 
00263 
00264 #endif
00265 
00266 /****************************************************************************/
00267 

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