Eclipse SUMO - Simulation of Urban MObility
RORouteDef.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2002-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
20 // Base class for a vehicle's route definition
21 /****************************************************************************/
22 #include <config.h>
23 
24 #include <string>
25 #include <iterator>
26 #include <algorithm>
28 #include <utils/common/ToString.h>
29 #include <utils/common/Named.h>
35 #include "ROEdge.h"
36 #include "RORoute.h"
39 #include "RORouteDef.h"
40 #include "ROVehicle.h"
41 
42 // ===========================================================================
43 // static members
44 // ===========================================================================
45 bool RORouteDef::myUsingJTRR(false);
46 
47 // ===========================================================================
48 // method definitions
49 // ===========================================================================
50 RORouteDef::RORouteDef(const std::string& id, const int lastUsed,
51  const bool tryRepair, const bool mayBeDisconnected) :
52  Named(StringUtils::convertUmlaute(id)),
53  myPrecomputed(nullptr), myLastUsed(lastUsed), myTryRepair(tryRepair),
54  myMayBeDisconnected(mayBeDisconnected),
55  myDiscardSilent(false) {
56 }
57 
58 
60  for (std::vector<RORoute*>::iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) {
61  if (myRouteRefs.count(*i) == 0) {
62  delete *i;
63  }
64  }
65 }
66 
67 
68 void
70  myAlternatives.push_back(alt);
71 }
72 
73 
74 void
76  std::copy(alt->myAlternatives.begin(), alt->myAlternatives.end(),
77  back_inserter(myAlternatives));
78  std::copy(alt->myAlternatives.begin(), alt->myAlternatives.end(),
79  std::inserter(myRouteRefs, myRouteRefs.end()));
80 }
81 
82 
83 RORoute*
85  SUMOTime begin, const ROVehicle& veh) const {
86  if (myPrecomputed == nullptr) {
87  preComputeCurrentRoute(router, begin, veh);
88  }
89  return myPrecomputed;
90 }
91 
92 
93 void
95  SUMOTime begin, const ROVehicle& veh) const {
96  myNewRoute = false;
98  const bool ignoreErrors = oc.getBool("ignore-errors");
99  assert(myAlternatives[0]->getEdgeVector().size() > 0);
101  if (myAlternatives[0]->getFirst()->prohibits(&veh) && (!oc.getBool("repair.from")
102  // do not try to reassign starting edge for trip input
103  || myMayBeDisconnected || myAlternatives[0]->getEdgeVector().size() < 2)) {
104  mh->inform("Vehicle '" + veh.getID() + "' is not allowed to depart on edge '" +
105  myAlternatives[0]->getFirst()->getID() + "'.");
106  return;
107  } else if (myAlternatives[0]->getLast()->prohibits(&veh) && (!oc.getBool("repair.to")
108  // do not try to reassign destination edge for trip input
109  || myMayBeDisconnected || myAlternatives[0]->getEdgeVector().size() < 2)) {
110  // this check is not strictly necessary unless myTryRepair is set.
111  // However, the error message is more helpful than "no connection found"
112  mh->inform("Vehicle '" + veh.getID() + "' is not allowed to arrive on edge '" +
113  myAlternatives[0]->getLast()->getID() + "'.");
114  return;
115  }
116  const bool skipTripRouting = (oc.exists("write-trips") && oc.getBool("write-trips")
118  if ((myTryRepair && !skipTripRouting) || myUsingJTRR) {
119  ConstROEdgeVector newEdges;
120  if (repairCurrentRoute(router, begin, veh, myAlternatives[0]->getEdgeVector(), newEdges)) {
121  if (myAlternatives[0]->getEdgeVector() != newEdges) {
122  if (!myMayBeDisconnected) {
123  WRITE_WARNINGF(TL("Repaired route of vehicle '%'."), veh.getID());
124  }
125  myNewRoute = true;
126  RGBColor* col = myAlternatives[0]->getColor() != nullptr ? new RGBColor(*myAlternatives[0]->getColor()) : nullptr;
127  myPrecomputed = new RORoute(myID, 0, myAlternatives[0]->getProbability(), newEdges, col, myAlternatives[0]->getStops());
128  } else {
130  }
131  }
132  return;
133  }
135  || OptionsCont::getOptions().getBool("remove-loops"))
136  && (skipTripRouting || myAlternatives[myLastUsed]->isValid(veh, ignoreErrors))) {
138  } else {
139  // build a new route to test whether it is better
140  ConstROEdgeVector oldEdges;
141  oldEdges.push_back(myAlternatives[0]->getFirst());
142  oldEdges.push_back(myAlternatives[0]->getLast());
143  ConstROEdgeVector edges;
144  repairCurrentRoute(router, begin, veh, oldEdges, edges);
145  // check whether the same route was already used
146  int cheapest = -1;
147  for (int i = 0; i < (int)myAlternatives.size(); i++) {
148  if (edges == myAlternatives[i]->getEdgeVector()) {
149  cheapest = i;
150  break;
151  }
152  }
153  if (cheapest >= 0) {
154  myPrecomputed = myAlternatives[cheapest];
155  } else {
156  RGBColor* col = myAlternatives[0]->getColor() != nullptr ? new RGBColor(*myAlternatives[0]->getColor()) : nullptr;
157  myPrecomputed = new RORoute(myID, 0, 1, edges, col, myAlternatives[0]->getStops());
158  myNewRoute = true;
159  }
160  }
161 }
162 
163 
164 bool
166  SUMOTime begin, const ROVehicle& veh,
167  ConstROEdgeVector oldEdges, ConstROEdgeVector& newEdges) const {
168  MsgHandler* mh = (OptionsCont::getOptions().getBool("ignore-errors") ?
170  const int initialSize = (int)oldEdges.size();
171  if (initialSize == 1) {
172  if (myUsingJTRR) {
174  bool ok = router.compute(oldEdges.front(), nullptr, &veh, begin, newEdges);
175  myDiscardSilent = ok && newEdges.size() == 0;
176  } else {
177  newEdges = oldEdges;
178  }
179  } else {
180  if (oldEdges.front()->prohibits(&veh)) {
181  // option repair.from is in effect
182  const std::string& frontID = oldEdges.front()->getID();
183  for (ConstROEdgeVector::iterator i = oldEdges.begin(); i != oldEdges.end();) {
184  if ((*i)->prohibits(&veh) || (*i)->isInternal()) {
185  i = oldEdges.erase(i);
186  } else {
187  WRITE_MESSAGE("Changing invalid starting edge '" + frontID
188  + "' to '" + (*i)->getID() + "' for vehicle '" + veh.getID() + "'.");
189  break;
190  }
191  }
192  }
193  if (oldEdges.size() == 0) {
194  mh->inform("Could not find new starting edge for vehicle '" + veh.getID() + "'.");
195  return false;
196  }
197  if (oldEdges.back()->prohibits(&veh)) {
198  // option repair.to is in effect
199  const std::string& backID = oldEdges.back()->getID();
200  // oldEdges cannot get empty here, otherwise we would have left the stage when checking "from"
201  while (oldEdges.back()->prohibits(&veh) || oldEdges.back()->isInternal()) {
202  oldEdges.pop_back();
203  }
204  WRITE_MESSAGE("Changing invalid destination edge '" + backID
205  + "' to edge '" + oldEdges.back()->getID() + "' for vehicle '" + veh.getID() + "'.");
206  }
207  ConstROEdgeVector mandatory = veh.getMandatoryEdges(oldEdges.front(), oldEdges.back());
208  std::set<ConstROEdgeVector::const_iterator> jumpStarts;
209  veh.collectJumps(mandatory, jumpStarts);
210  assert(mandatory.size() >= 2);
211  // removed prohibited
212  for (ConstROEdgeVector::iterator i = oldEdges.begin(); i != oldEdges.end();) {
213  if ((*i)->prohibits(&veh) || (*i)->isInternal()) {
214  // no need to check the mandatories here, this was done before
215  i = oldEdges.erase(i);
216  } else {
217  ++i;
218  }
219  }
220  // reconnect remaining edges
221  if (mandatory.size() > oldEdges.size() && initialSize > 2) {
222  WRITE_MESSAGEF(TL("There are stop edges which were not part of the original route for vehicle '%'."), veh.getID());
223  }
224  const ConstROEdgeVector& targets = mandatory.size() > oldEdges.size() ? mandatory : oldEdges;
225  newEdges.push_back(targets.front());
226  ConstROEdgeVector::iterator nextMandatory = mandatory.begin() + 1;
227  int lastMandatory = 0;
228  for (ConstROEdgeVector::const_iterator i = targets.begin() + 1;
229  i != targets.end() && nextMandatory != mandatory.end(); ++i) {
230  const ROEdge* prev = *(i - 1);
231  const ROEdge* cur = *i;
232  if (prev->isConnectedTo(*cur, veh.getVClass()) && (!isRailway(veh.getVClass()) || prev->getBidiEdge() != cur)) {
233  newEdges.push_back(cur);
234  } else {
235  if (initialSize > 2) {
236  // only inform if the input is (probably) not a trip
237  WRITE_MESSAGEF(TL("Edge '%' not connected to edge '%' for vehicle '%'."), (*(i - 1))->getID(), (*i)->getID(), veh.getID());
238  }
239  const ROEdge* last = newEdges.back();
240  newEdges.pop_back();
241  if (last->isTazConnector() && newEdges.size() > 1) {
242  // assume this was a viaTaz
243  last = newEdges.back();
244  newEdges.pop_back();
245  }
246  if (veh.hasJumps() && jumpStarts.count(nextMandatory - 1) != 0) {
247  while (*i != *nextMandatory) {
248  ++i;
249  }
250  newEdges.push_back(last);
251  newEdges.push_back(*i);
252  //std::cout << " skipJump mIndex=" << (nextMandatory - 1 - mandatory.begin()) << " last=" << last->getID() << " next=" << (*i)->getID() << " newEdges=" << toString(newEdges) << "\n";
253  } else {
254 
255  // router.setHint(targets.begin(), i, &veh, begin);
256  if (!router.compute(last, *i, &veh, begin, newEdges)) {
257  // backtrack: try to route from last mandatory edge to next mandatory edge
258  // XXX add option for backtracking in smaller increments
259  // (i.e. previous edge to edge after *i)
260  // we would then need to decide whether we have found a good
261  // tradeoff between faithfulness to the input data and detour-length
262  ConstROEdgeVector edges;
263  if (lastMandatory >= (int)newEdges.size() || last == newEdges[lastMandatory] || !router.compute(newEdges[lastMandatory], *nextMandatory, &veh, begin, edges)) {
264  mh->inform("Mandatory edge '" + (*i)->getID() + "' not reachable by vehicle '" + veh.getID() + "'.");
265  return false;
266  }
267  while (*i != *nextMandatory) {
268  ++i;
269  }
270  newEdges.erase(newEdges.begin() + lastMandatory + 1, newEdges.end());
271  std::copy(edges.begin() + 1, edges.end(), back_inserter(newEdges));
272  }
273 
274  }
275  }
276  if (*i == *nextMandatory) {
277  nextMandatory++;
278  lastMandatory = (int)newEdges.size() - 1;
279  }
280  }
281  }
282  return true;
283 }
284 
285 
286 void
288  const ROVehicle* const veh, RORoute* current, SUMOTime begin) {
289  if (myTryRepair || myUsingJTRR) {
290  if (myNewRoute) {
291  delete myAlternatives[0];
292  myAlternatives[0] = current;
293  }
294  if (!router.isValid(current->getEdgeVector(), veh)) {
295  throw ProcessError("Route '" + getID() + "' (vehicle '" + veh->getID() + "') is not valid.");
296  }
297  double costs = router.recomputeCosts(current->getEdgeVector(), veh, begin);
298  if (veh->hasJumps()) {
299  // @todo: jumpTime should be applied in recomputeCost to ensure the
300  // correctness of time-dependent traveltimes
301  costs += STEPS2TIME(veh->getJumpTime());
302  }
303  current->setCosts(costs);
304  return;
305  }
306  // add the route when it's new
307  if (myNewRoute) {
308  myAlternatives.push_back(current);
309  }
310  // recompute the costs and (when a new route was added) scale the probabilities
311  const double scale = double(myAlternatives.size() - 1) / double(myAlternatives.size());
312  for (RORoute* const alt : myAlternatives) {
313  if (!router.isValid(alt->getEdgeVector(), veh)) {
314  throw ProcessError("Route '" + current->getID() + "' (vehicle '" + veh->getID() + "') is not valid.");
315  }
316  // recompute the costs for all routes
317  const double newCosts = router.recomputeCosts(alt->getEdgeVector(), veh, begin);
318  assert(myAlternatives.size() != 0);
319  if (myNewRoute) {
320  if (alt == current) {
321  // set initial probability and costs
322  alt->setProbability(1. / (double) myAlternatives.size());
323  alt->setCosts(newCosts);
324  } else {
325  // rescale probs for all others
326  alt->setProbability(alt->getProbability() * scale);
327  }
328  }
330  }
331  assert(myAlternatives.size() != 0);
333  const bool keepRoute = RouteCostCalculator<RORoute, ROEdge, ROVehicle>::getCalculator().keepRoute();
334  if (!RouteCostCalculator<RORoute, ROEdge, ROVehicle>::getCalculator().keepAllRoutes() && !keepRoute) {
335  // remove with probability of 0 (not mentioned in Gawron)
336  for (std::vector<RORoute*>::iterator i = myAlternatives.begin(); i != myAlternatives.end();) {
337  if ((*i)->getProbability() == 0) {
338  delete *i;
339  i = myAlternatives.erase(i);
340  } else {
341  i++;
342  }
343  }
344  }
345  int maxNumber = RouteCostCalculator<RORoute, ROEdge, ROVehicle>::getCalculator().getMaxRouteNumber();
346  if ((int)myAlternatives.size() > maxNumber) {
347  const RORoute* last = myAlternatives[myLastUsed];
348  // only keep the routes with highest probability
349  sort(myAlternatives.begin(), myAlternatives.end(), [](const RORoute * const a, const RORoute * const b) {
350  return a->getProbability() > b->getProbability();
351  });
352  if (keepRoute) {
353  for (int i = 0; i < (int)myAlternatives.size(); i++) {
354  if (myAlternatives[i] == last) {
355  myLastUsed = i;
356  break;
357  }
358  }
359  if (myLastUsed >= maxNumber) {
361  myLastUsed = maxNumber - 1;
362  }
363  }
364  for (std::vector<RORoute*>::iterator i = myAlternatives.begin() + maxNumber; i != myAlternatives.end(); i++) {
365  delete *i;
366  }
367  myAlternatives.erase(myAlternatives.begin() + maxNumber, myAlternatives.end());
368  }
369  // rescale probabilities
370  double newSum = 0.;
371  for (const RORoute* const alt : myAlternatives) {
372  newSum += alt->getProbability();
373  }
374  assert(newSum > 0);
375  // @note newSum may be larger than 1 for numerical reasons
376  for (RORoute* const alt : myAlternatives) {
377  alt->setProbability(alt->getProbability() / newSum);
378  }
379 
380  // find the route to use
381  if (!keepRoute) {
382  double chosen = RandHelper::rand();
383  myLastUsed = 0;
384  for (const RORoute* const alt : myAlternatives) {
385  chosen -= alt->getProbability();
386  if (chosen <= 0) {
387  return;
388  }
389  myLastUsed++;
390  }
391  }
392 }
393 
394 
395 const ROEdge*
397  return myAlternatives[0]->getLast();
398 }
399 
400 
403  bool asAlternatives, bool withExitTimes, bool withCost, bool withLength) const {
404  if (asAlternatives) {
406  for (int i = 0; i != (int)myAlternatives.size(); i++) {
407  myAlternatives[i]->writeXMLDefinition(dev, veh, true, true, withExitTimes, withLength);
408  }
409  dev.closeTag();
410  return dev;
411  } else {
412  return myAlternatives[myLastUsed]->writeXMLDefinition(dev, veh, withCost, false, withExitTimes, withLength);
413  }
414 }
415 
416 
417 RORouteDef*
418 RORouteDef::copy(const std::string& id, const SUMOTime stopOffset) const {
419  RORouteDef* result = new RORouteDef(id, 0, myTryRepair, myMayBeDisconnected);
420  for (const RORoute* const route : myAlternatives) {
421  RGBColor* col = route->getColor() != nullptr ? new RGBColor(*route->getColor()) : nullptr;
422  RORoute* newRoute = new RORoute(id, route->getCosts(), route->getProbability(), route->getEdgeVector(), col, route->getStops());
423  newRoute->addStopOffset(stopOffset);
424  result->addLoadedAlternative(newRoute);
425  }
426  return result;
427 }
428 
429 
430 double
432  double sum = 0.;
433  for (std::vector<RORoute*>::const_iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) {
434  sum += (*i)->getProbability();
435  }
436  return sum;
437 }
438 
439 
440 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:296
#define WRITE_MESSAGEF(...)
Definition: MsgHandler.h:298
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:297
#define TL(string)
Definition: MsgHandler.h:315
std::vector< const ROEdge * > ConstROEdgeVector
Definition: ROEdge.h:54
#define STEPS2TIME(x)
Definition: SUMOTime.h:55
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
@ SUMO_TAG_ROUTE_DISTRIBUTION
distribution of a route
@ SUMO_ATTR_LAST
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:92
virtual void inform(std::string msg, bool addType=true)
adds a new error to the list
Definition: MsgHandler.cpp:154
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
Definition: MsgHandler.cpp:79
Base class for objects which have an id.
Definition: Named.h:54
std::string myID
The name of the object.
Definition: Named.h:125
const std::string & getID() const
Returns the id.
Definition: Named.h:74
A storage for options typed value containers)
Definition: OptionsCont.h:89
bool exists(const std::string &name) const
Returns the information whether the named option is known.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:60
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:254
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
A basic edge for routing applications.
Definition: ROEdge.h:70
bool isTazConnector() const
Definition: ROEdge.h:168
const ROEdge * getBidiEdge() const
return opposite superposable/congruent edge, if it exist and 0 else
Definition: ROEdge.h:529
bool isConnectedTo(const ROEdge &e, const SUMOVehicleClass vClass) const
returns the information whether this edge is directly connected to the given
Definition: ROEdge.cpp:438
const std::string & getID() const
Returns the id of the routable.
Definition: RORoutable.h:91
SUMOVehicleClass getVClass() const
Definition: RORoutable.h:109
Base class for a vehicle's route definition.
Definition: RORouteDef.h:53
RORoute * myPrecomputed
precomputed route for out-of-order computation
Definition: RORouteDef.h:148
void addLoadedAlternative(RORoute *alternative)
Adds a single alternative loaded from the file An alternative may also be generated during DUA.
Definition: RORouteDef.cpp:69
RORouteDef(const std::string &id, const int lastUsed, const bool tryRepair, const bool mayBeDisconnected)
Constructor.
Definition: RORouteDef.cpp:50
double getOverallProb() const
Returns the sum of the probablities of the contained routes.
Definition: RORouteDef.cpp:431
std::vector< RORoute * > myAlternatives
The alternatives.
Definition: RORouteDef.h:154
OutputDevice & writeXMLDefinition(OutputDevice &dev, const ROVehicle *const veh, bool asAlternatives, bool withExitTimes, bool withCost, bool withLength) const
Saves the built route / route alternatives.
Definition: RORouteDef.cpp:402
RORoute * buildCurrentRoute(SUMOAbstractRouter< ROEdge, ROVehicle > &router, SUMOTime begin, const ROVehicle &veh) const
Triggers building of the complete route (via preComputeCurrentRoute) or returns precomputed route.
Definition: RORouteDef.cpp:84
const bool myMayBeDisconnected
Definition: RORouteDef.h:163
void addAlternativeDef(const RORouteDef *alternative)
Adds an alternative loaded from the file.
Definition: RORouteDef.cpp:75
virtual ~RORouteDef()
Destructor.
Definition: RORouteDef.cpp:59
bool myDiscardSilent
Whether this route should be silently discarded.
Definition: RORouteDef.h:166
void preComputeCurrentRoute(SUMOAbstractRouter< ROEdge, ROVehicle > &router, SUMOTime begin, const ROVehicle &veh) const
Builds the complete route (or chooses her from the list of alternatives, when existing)
Definition: RORouteDef.cpp:94
static bool myUsingJTRR
Definition: RORouteDef.h:168
bool myNewRoute
Information whether a new route was generated.
Definition: RORouteDef.h:160
void addAlternative(SUMOAbstractRouter< ROEdge, ROVehicle > &router, const ROVehicle *const, RORoute *current, SUMOTime begin)
Adds an alternative to the list of routes.
Definition: RORouteDef.cpp:287
const bool myTryRepair
Definition: RORouteDef.h:162
int myLastUsed
Index of the route used within the last step.
Definition: RORouteDef.h:151
std::set< RORoute * > myRouteRefs
Routes which are deleted someplace else.
Definition: RORouteDef.h:157
const ROEdge * getDestination() const
Definition: RORouteDef.cpp:396
RORouteDef * copy(const std::string &id, const SUMOTime stopOffset) const
Returns a deep copy of the route definition.
Definition: RORouteDef.cpp:418
bool repairCurrentRoute(SUMOAbstractRouter< ROEdge, ROVehicle > &router, SUMOTime begin, const ROVehicle &veh, ConstROEdgeVector oldEdges, ConstROEdgeVector &newEdges) const
Builds the complete route (or chooses her from the list of alternatives, when existing)
Definition: RORouteDef.cpp:165
A complete router's route.
Definition: RORoute.h:52
void addStopOffset(const SUMOTime offset)
Adapts the until time of all stops by the given offset.
Definition: RORoute.h:193
const ConstROEdgeVector & getEdgeVector() const
Returns the list of edges this route consists of.
Definition: RORoute.h:152
void setCosts(double costs)
Sets the costs of the route.
Definition: RORoute.cpp:64
A vehicle as used by router.
Definition: ROVehicle.h:50
void collectJumps(const ConstROEdgeVector &mandatory, std::set< ConstROEdgeVector::const_iterator > &jumpStarts) const
collect mandatory-edge iterators that define jumps in the route
Definition: ROVehicle.cpp:214
SUMOTime getJumpTime() const
Definition: ROVehicle.h:129
SUMOTime getDepartureTime() const
Returns the time the vehicle starts at, 0 for triggered vehicles.
Definition: ROVehicle.h:92
ConstROEdgeVector getMandatoryEdges(const ROEdge *requiredStart, const ROEdge *requiredEnd) const
compute mandatory edges
Definition: ROVehicle.cpp:184
bool hasJumps() const
Definition: ROVehicle.h:125
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
Definition: RandHelper.cpp:94
Abstract base class providing static factory method.
static RouteCostCalculator< R, E, V > & getCalculator()
bool isValid(const std::vector< const E * > &edges, const V *const v) const
virtual bool compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into, bool silent=false)=0
Builds the route between the given edges using the minimum effort at the given time The definition of...
virtual double recomputeCosts(const std::vector< const E * > &edges, const V *const v, SUMOTime msTime, double *lengthp=nullptr) const
Some static methods for string processing.
Definition: StringUtils.h:40
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition: json.hpp:21884