00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef DijkstraRouterTT_h
00020 #define DijkstraRouterTT_h
00021
00022
00023
00024
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
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
00132 EdgeInfo* const fromInfo = &(myEdgeInfos[from->getNumericalID()]);
00133 fromInfo->traveltime = 0;
00134 fromInfo->prev = 0;
00135 myFrontierList.push_back(fromInfo);
00136
00137 while (!myFrontierList.empty()) {
00138
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
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
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
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