SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RORouteDef.cpp
Go to the documentation of this file.
1 /****************************************************************************/
8 // Base class for a vehicle's route definition
9 /****************************************************************************/
10 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
11 // Copyright (C) 2001-2013 DLR (http://www.dlr.de/) and contributors
12 /****************************************************************************/
13 //
14 // This file is part of SUMO.
15 // SUMO is free software: you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation, either version 3 of the License, or
18 // (at your option) any later version.
19 //
20 /****************************************************************************/
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #ifdef _MSC_VER
27 #include <windows_config.h>
28 #else
29 #include <config.h>
30 #endif
31 
32 #include <string>
33 #include <iterator>
35 #include <utils/common/ToString.h>
36 #include <utils/common/Named.h>
42 #include "ROEdge.h"
43 #include "RORoute.h"
45 #include "ReferencedItem.h"
46 #include "RORouteDef.h"
47 #include "ROVehicle.h"
48 #include "ROCostCalculator.h"
49 
50 #ifdef CHECK_MEMORY_LEAKS
51 #include <foreign/nvwa/debug_new.h>
52 #endif // CHECK_MEMORY_LEAKS
53 
54 
55 // ===========================================================================
56 // method definitions
57 // ===========================================================================
58 RORouteDef::RORouteDef(const std::string& id, const unsigned int lastUsed,
59  const bool tryRepair) :
60  ReferencedItem(), Named(StringUtils::convertUmlaute(id)),
61  myPrecomputed(0), myLastUsed(lastUsed), myTryRepair(tryRepair)
62 {}
63 
64 
66  for (std::vector<RORoute*>::iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) {
67  delete *i;
68  }
69 }
70 
71 
72 void
74  myAlternatives.push_back(alt);
75 }
76 
77 
78 void
80  std::copy(alt->myAlternatives.begin(), alt->myAlternatives.end(),
81  back_inserter(myAlternatives));
82 }
83 
84 
85 RORoute*
87  SUMOTime begin, const ROVehicle& veh) const {
88  if (myPrecomputed == 0) {
89  preComputeCurrentRoute(router, begin, veh);
90  }
91  return myPrecomputed;
92 }
93 
94 
95 void
97  SUMOTime begin, const ROVehicle& veh) const {
98  myNewRoute = false;
99  if (myTryRepair) {
100  repairCurrentRoute(router, begin, veh);
101  return;
102  }
103  if (ROCostCalculator::getCalculator().skipRouteCalculation()) {
105  } else {
106  // build a new route to test whether it is better
107  std::vector<const ROEdge*> edges;
108  router.compute(myAlternatives[0]->getFirst(), myAlternatives[0]->getLast(), &veh, begin, edges);
109  // check whether the same route was already used
110  int cheapest = -1;
111  for (unsigned int i = 0; i < myAlternatives.size(); i++) {
112  if (edges == myAlternatives[i]->getEdgeVector()) {
113  cheapest = i;
114  break;
115  }
116  }
117  if (cheapest >= 0) {
118  myPrecomputed = myAlternatives[cheapest];
119  } else {
120  RGBColor* col = myAlternatives[0]->getColor() != 0 ? new RGBColor(*myAlternatives[0]->getColor()) : 0;
121  myPrecomputed = new RORoute(myID, 0, 1, edges, col);
122  myNewRoute = true;
123  }
124  }
125 }
126 
127 
128 void
130  SUMOTime begin, const ROVehicle& veh) const {
131  const std::vector<const ROEdge*>& oldEdges = myAlternatives[0]->getEdgeVector();
132  if (oldEdges.size() == 0) {
134  m->inform("Could not repair empty route of vehicle '" + veh.getID() + "'.");
135  return;
136  }
137  std::vector<const ROEdge*> newEdges;
138  if (oldEdges.size() == 1) {
140  router.compute(oldEdges.front(), oldEdges.front(), &veh, begin, newEdges);
141  } else {
142  newEdges.push_back(*(oldEdges.begin()));
143  for (std::vector<const ROEdge*>::const_iterator i = oldEdges.begin() + 1; i != oldEdges.end(); ++i) {
144  if ((*(i - 1))->isConnectedTo(*i)) {
145  newEdges.push_back(*i);
146  } else {
147  std::vector<const ROEdge*> edges;
148  router.compute(*(i - 1), *i, &veh, begin, edges);
149  if (edges.size() == 0) {
150  return;
151  }
152  std::copy(edges.begin() + 1, edges.end(), back_inserter(newEdges));
153  }
154  }
155  }
156  if (myAlternatives[0]->getEdgeVector() != newEdges) {
157  WRITE_MESSAGE("Repaired route of vehicle '" + veh.getID() + "'.");
158  myNewRoute = true;
159  RGBColor* col = myAlternatives[0]->getColor() != 0 ? new RGBColor(*myAlternatives[0]->getColor()) : 0;
160  myPrecomputed = new RORoute(myID, 0, 1, newEdges, col);
161  } else {
163  }
164 }
165 
166 
167 void
169  const ROVehicle* const veh, RORoute* current, SUMOTime begin) {
170  if (myTryRepair) {
171  if (myNewRoute) {
172  delete myAlternatives[0];
173  myAlternatives.pop_back();
174  myAlternatives.push_back(current);
175  }
176  const SUMOReal costs = router.recomputeCosts(current->getEdgeVector(), veh, begin);
177  if (costs < 0) {
178  throw ProcessError("Route '" + getID() + "' (vehicle '" + veh->getID() + "') is not valid.");
179  }
180  current->setCosts(costs);
181  return;
182  }
183  // add the route when it's new
184  if (myNewRoute) {
185  myAlternatives.push_back(current);
186  }
187  // recompute the costs and (when a new route was added) scale the probabilities
188  const SUMOReal scale = SUMOReal(myAlternatives.size() - 1) / SUMOReal(myAlternatives.size());
189  for (std::vector<RORoute*>::iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) {
190  RORoute* alt = *i;
191  // recompute the costs for all routes
192  const SUMOReal newCosts = router.recomputeCosts(alt->getEdgeVector(), veh, begin);
193  if (newCosts < 0.) {
194  throw ProcessError("Route '" + current->getID() + "' (vehicle '" + veh->getID() + "') is not valid.");
195  }
196  assert(myAlternatives.size() != 0);
197  if (myNewRoute) {
198  if (*i == current) {
199  // set initial probability and costs
200  alt->setProbability((SUMOReal)(1.0 / (SUMOReal) myAlternatives.size()));
201  alt->setCosts(newCosts);
202  } else {
203  // rescale probs for all others
204  alt->setProbability(alt->getProbability() * scale);
205  }
206  }
208  }
209  assert(myAlternatives.size() != 0);
211  if (!ROCostCalculator::getCalculator().keepRoutes()) {
212  // remove with probability of 0 (not mentioned in Gawron)
213  for (std::vector<RORoute*>::iterator i = myAlternatives.begin(); i != myAlternatives.end();) {
214  if ((*i)->getProbability() == 0) {
215  delete *i;
216  i = myAlternatives.erase(i);
217  } else {
218  i++;
219  }
220  }
221  }
223  // only keep the routes with highest probability
224  sort(myAlternatives.begin(), myAlternatives.end(), ComparatorProbability());
225  for (std::vector<RORoute*>::iterator i = myAlternatives.begin() + ROCostCalculator::getCalculator().getMaxRouteNumber(); i != myAlternatives.end(); i++) {
226  delete *i;
227  }
229  // rescale probabilities
230  SUMOReal newSum = 0;
231  for (std::vector<RORoute*>::iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) {
232  newSum += (*i)->getProbability();
233  }
234  assert(newSum > 0);
235  // @note newSum may be larger than 1 for numerical reasons
236  for (std::vector<RORoute*>::iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) {
237  (*i)->setProbability((*i)->getProbability() / newSum);
238  }
239  }
240 
241  // find the route to use
242  SUMOReal chosen = RandHelper::rand();
243  int pos = 0;
244  for (std::vector<RORoute*>::iterator i = myAlternatives.begin(); i != myAlternatives.end() - 1; i++, pos++) {
245  chosen -= (*i)->getProbability();
246  if (chosen <= 0) {
247  myLastUsed = pos;
248  return;
249  }
250  }
251  myLastUsed = pos;
252 }
253 
254 
255 const ROEdge*
257  return myAlternatives[0]->getLast();
258 }
259 
260 
263  bool asAlternatives, bool withExitTimes) const {
264  if (asAlternatives) {
266  for (size_t i = 0; i != myAlternatives.size(); i++) {
267  myAlternatives[i]->writeXMLDefinition(dev, veh, true, withExitTimes);
268  }
269  dev.closeTag();
270  return dev;
271  } else {
272  return myAlternatives[myLastUsed]->writeXMLDefinition(dev, veh, false, withExitTimes);
273  }
274 }
275 
276 
277 RORouteDef*
278 RORouteDef::copyOrigDest(const std::string& id) const {
279  RORouteDef* result = new RORouteDef(id, 0, true);
280  RORoute* route = myAlternatives[0];
281  RGBColor* col = route->getColor() != 0 ? new RGBColor(*route->getColor()) : 0;
282  std::vector<const ROEdge*> edges;
283  edges.push_back(route->getFirst());
284  edges.push_back(route->getLast());
285  result->addLoadedAlternative(new RORoute(id, 0, 1, edges, col));
286  return result;
287 }
288 
289 
290 RORouteDef*
291 RORouteDef::copy(const std::string& id) const {
292  RORouteDef* result = new RORouteDef(id, 0, myTryRepair);
293  for (std::vector<RORoute*>::const_iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) {
294  RORoute* route = *i;
295  RGBColor* col = route->getColor() != 0 ? new RGBColor(*route->getColor()) : 0;
296  result->addLoadedAlternative(new RORoute(id, 0, 1, route->getEdgeVector(), col));
297  }
298  return result;
299 }
300 
301 
302 SUMOReal
304  SUMOReal sum = 0.;
305  for (std::vector<RORoute*>::const_iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) {
306  sum += (*i)->getProbability();
307  }
308  return sum;
309 }
310 
311 
312 /****************************************************************************/