SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DijkstraRouterTT.h
Go to the documentation of this file.
1 /****************************************************************************/
9 // Dijkstra shortest path algorithm using travel time
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
12 // Copyright (C) 2001-2015 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 /****************************************************************************/
22 #ifndef DijkstraRouterTT_h
23 #define DijkstraRouterTT_h
24 
25 
26 // ===========================================================================
27 // included modules
28 // ===========================================================================
29 #ifdef _MSC_VER
30 #include <windows_config.h>
31 #else
32 #include <config.h>
33 #endif
34 
35 #include <cassert>
36 #include <string>
37 #include <functional>
38 #include <vector>
39 #include <deque>
40 #include <set>
41 #include <limits>
42 #include <algorithm>
43 #include <iterator>
44 #include <utils/common/ToString.h>
46 #include <utils/common/StdDefs.h>
47 #include "SUMOAbstractRouter.h"
48 
49 //#define DijkstraRouterTT_DEBUG_QUERY
50 //#define DijkstraRouterTT_DEBUG_QUERY_PERF
51 
52 // ===========================================================================
53 // class definitions
54 // ===========================================================================
70 template<class E, class V, class PF>
71 class DijkstraRouterTT : public SUMOAbstractRouter<E, V>, public PF {
72 
73 public:
74  typedef SUMOReal(* Operation)(const E* const, const V* const, SUMOReal);
76  DijkstraRouterTT(size_t noE, bool unbuildIsWarning, Operation operation) :
77  SUMOAbstractRouter<E, V>(operation, "DijkstraRouterTT"),
78  myErrorMsgHandler(unbuildIsWarning ? MsgHandler::getWarningInstance() : MsgHandler::getErrorInstance()) {
79  for (size_t i = 0; i < noE; i++) {
80  myEdgeInfos.push_back(EdgeInfo(i));
81  }
82  }
83 
85  virtual ~DijkstraRouterTT() { }
86 
87  virtual SUMOAbstractRouter<E, V>* clone() const {
89  }
90 
96  class EdgeInfo {
97  public:
99  EdgeInfo(size_t id)
100  : edge(E::dictionary(id)), traveltime(std::numeric_limits<SUMOReal>::max()), prev(0), visited(false) {}
101 
103  const E* edge;
104 
107 
110 
112  bool visited;
113 
114  inline void reset() {
116  visited = false;
117  }
118  };
119 
125  public:
127  bool operator()(const EdgeInfo* nod1, const EdgeInfo* nod2) const {
128  if (nod1->traveltime == nod2->traveltime) {
129  return nod1->edge->getNumericalID() > nod2->edge->getNumericalID();
130  }
131  return nod1->traveltime > nod2->traveltime;
132  }
133  };
134 
135  void init() {
136  // all EdgeInfos touched in the previous query are either in myFrontierList or myFound: clean those up
137  for (typename std::vector<EdgeInfo*>::iterator i = myFrontierList.begin(); i != myFrontierList.end(); i++) {
138  (*i)->reset();
139  }
140  myFrontierList.clear();
141  for (typename std::vector<EdgeInfo*>::iterator i = myFound.begin(); i != myFound.end(); i++) {
142  (*i)->reset();
143  }
144  myFound.clear();
145  }
146 
147 
150  virtual void compute(const E* from, const E* to, const V* const vehicle,
151  SUMOTime msTime, std::vector<const E*>& into) {
152  assert(from != 0 && (vehicle == 0 || to != 0));
153  this->startQuery();
154  const SUMOVehicleClass vClass = vehicle == 0 ? SVC_IGNORING : vehicle->getVClass();
155  const SUMOReal time = STEPS2TIME(msTime);
156  if (this->myBulkMode) {
157  const EdgeInfo& toInfo = myEdgeInfos[to->getNumericalID()];
158  if (toInfo.visited) {
159  buildPathFrom(&toInfo, into);
160  this->endQuery(1);
161  return;
162  }
163  } else {
164  init();
165  // add begin node
166  EdgeInfo* const fromInfo = &(myEdgeInfos[from->getNumericalID()]);
167  fromInfo->traveltime = 0;
168  fromInfo->prev = 0;
169  myFrontierList.push_back(fromInfo);
170  }
171  // loop
172  int num_visited = 0;
173  while (!myFrontierList.empty()) {
174  num_visited += 1;
175  // use the node with the minimal length
176  EdgeInfo* const minimumInfo = myFrontierList.front();
177  const E* const minEdge = minimumInfo->edge;
178  // check whether the destination node was already reached
179  if (minEdge == to) {
180  buildPathFrom(minimumInfo, into);
181  this->endQuery(num_visited);
182 #ifdef DijkstraRouterTT_DEBUG_QUERY_PERF
183  std::cout << "visited " + toString(num_visited) + " edges (final path length: " + toString(into.size()) + ")\n";
184 #endif
185  return;
186  }
187  pop_heap(myFrontierList.begin(), myFrontierList.end(), myComparator);
188  myFrontierList.pop_back();
189  myFound.push_back(minimumInfo);
190  minimumInfo->visited = true;
191 #ifdef DijkstraRouterTT_DEBUG_QUERY
192  std::cout << "DEBUG: hit '" << minEdge->getID() << "' TT: " << minimumInfo->traveltime << " Q: ";
193  for (typename std::vector<EdgeInfo*>::iterator it = myFrontierList.begin(); it != myFrontierList.end(); it++) {
194  std::cout << (*it)->traveltime << "," << (*it)->edge->getID() << " ";
195  }
196  std::cout << "\n";
197 #endif
198  const SUMOReal traveltime = minimumInfo->traveltime + this->getEffort(minEdge, vehicle, time + minimumInfo->traveltime);
199  // check all ways from the node with the minimal length
200  const std::vector<E*>& successors = minEdge->getSuccessors(vClass);
201  for (typename std::vector<E*>::const_iterator it = successors.begin(); it != successors.end(); ++it) {
202  const E* const follower = *it;
203  EdgeInfo* const followerInfo = &(myEdgeInfos[follower->getNumericalID()]);
204  // check whether it can be used
205  if (PF::operator()(follower, vehicle)) {
206  continue;
207  }
208  const SUMOReal oldEffort = followerInfo->traveltime;
209  if (!followerInfo->visited && traveltime < oldEffort) {
210  followerInfo->traveltime = traveltime;
211  followerInfo->prev = minimumInfo;
212  if (oldEffort == std::numeric_limits<SUMOReal>::max()) {
213  myFrontierList.push_back(followerInfo);
214  push_heap(myFrontierList.begin(), myFrontierList.end(), myComparator);
215  } else {
216  push_heap(myFrontierList.begin(),
217  find(myFrontierList.begin(), myFrontierList.end(), followerInfo) + 1,
218  myComparator);
219  }
220  }
221  }
222  }
223  this->endQuery(num_visited);
224 #ifdef DijkstraRouterTT_DEBUG_QUERY_PERF
225  std::cout << "visited " + toString(num_visited) + " edges (final path length: " + toString(into.size()) + ")\n";
226 #endif
227  if (to != 0) {
228  myErrorMsgHandler->inform("No connection between '" + from->getID() + "' and '" + to->getID() + "' found.");
229  }
230  }
231 
232 
233  SUMOReal recomputeCosts(const std::vector<const E*>& edges, const V* const v, SUMOTime msTime) const {
234  const SUMOReal time = STEPS2TIME(msTime);
235  SUMOReal costs = 0;
236  for (typename std::vector<const E*>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
237  if (PF::operator()(*i, v)) {
238  return -1;
239  }
240  costs += this->getEffort(*i, v, time + costs);
241  }
242  return costs;
243  }
244 
245 public:
247  void buildPathFrom(const EdgeInfo* rbegin, std::vector<const E*>& edges) {
248  std::vector<const E*> tmp;
249  while (rbegin != 0) {
250  tmp.push_back(rbegin->edge);
251  rbegin = rbegin->prev;
252  }
253  std::copy(tmp.rbegin(), tmp.rend(), std::back_inserter(edges));
254  }
255 
256  const EdgeInfo& getEdgeInfo(size_t index) const {
257  return myEdgeInfos[index];
258  }
259 
260 private:
262  std::vector<EdgeInfo> myEdgeInfos;
263 
265  std::vector<EdgeInfo*> myFrontierList;
267  std::vector<EdgeInfo*> myFound;
268 
269  EdgeInfoByTTComparator myComparator;
270 
273 };
274 
275 
276 #endif
277 
278 /****************************************************************************/
279 
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
Definition: MsgHandler.cpp:71
EdgeInfo(size_t id)
Constructor.
virtual ~DijkstraRouterTT()
Destructor.
SUMOReal recomputeCosts(const std::vector< const E * > &edges, const V *const v, SUMOTime msTime) const
bool visited
The previous edge.
virtual void compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into)
Builds the route between the given edges using the minimum effort at the given time The definition of...
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types...
const E * edge
The current edge.
SUMOReal(* Operation)(const E *const, const V *const, SUMOReal)
const EdgeInfo & getEdgeInfo(size_t index) const
Computes the shortest path through a network using the Dijkstra algorithm.
void buildPathFrom(const EdgeInfo *rbegin, std::vector< const E * > &edges)
Builds the path from marked edges.
SUMOReal traveltime
Effort to reach the edge.
bool operator()(const EdgeInfo *nod1, const EdgeInfo *nod2) const
Comparing method.
#define max(a, b)
Definition: polyfonts.c:65
MsgHandler *const myErrorMsgHandler
the handler for routing errors
bool myBulkMode
whether we are currently operating several route queries in a bulk
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
EdgeInfoByTTComparator myComparator
Operation myOperation
The object&#39;s operation to perform.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
std::vector< EdgeInfo * > myFound
list of visited Edges (for resetting)
std::vector< EdgeInfo > myEdgeInfos
The container of edge information.
virtual SUMOAbstractRouter< E, V > * clone() const
void inform(std::string msg, bool addType=true)
adds a new error to the list
Definition: MsgHandler.cpp:89
std::vector< EdgeInfo * > myFrontierList
A container for reusage of the min edge heap.
#define SUMOReal
Definition: config.h:215
void endQuery(int visits)
EdgeInfo * prev
The previous edge.
DijkstraRouterTT(size_t noE, bool unbuildIsWarning, Operation operation)
Constructor.
SUMOReal getEffort(const E *const e, const V *const v, SUMOReal t) const
vehicles ignoring classes