00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef DijkstraRouterEffort_h
00020 #define DijkstraRouterEffort_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 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
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
00145 while (!myFrontierList.empty()) {
00146
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
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
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
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