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-2012 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  newEdges.push_back(*(oldEdges.begin()));
139  for (std::vector<const ROEdge*>::const_iterator i = oldEdges.begin() + 1; i != oldEdges.end(); ++i) {
140  if ((*(i - 1))->isConnectedTo(*i)) {
141  newEdges.push_back(*i);
142  } else {
143  std::vector<const ROEdge*> edges;
144  router.compute(*(i - 1), *i, &veh, begin, edges);
145  if (edges.size() == 0) {
146  return;
147  }
148  std::copy(edges.begin() + 1, edges.end(), back_inserter(newEdges));
149  }
150  }
151  if (myAlternatives[0]->getEdgeVector() != newEdges) {
152  WRITE_MESSAGE("Repaired route of vehicle '" + veh.getID() + "'.");
153  myNewRoute = true;
154  RGBColor* col = myAlternatives[0]->getColor() != 0 ? new RGBColor(*myAlternatives[0]->getColor()) : 0;
155  myPrecomputed = new RORoute(myID, 0, 1, newEdges, col);
156  } else {
158  }
159 }
160 
161 
162 void
164  const ROVehicle* const veh, RORoute* current, SUMOTime begin) {
165  if (myTryRepair) {
166  if (myNewRoute) {
167  delete myAlternatives[0];
168  myAlternatives.pop_back();
169  myAlternatives.push_back(current);
170  }
171  const SUMOReal costs = router.recomputeCosts(current->getEdgeVector(), veh, begin);
172  if (costs < 0) {
173  throw ProcessError("Route '" + getID() + "' (vehicle '" + veh->getID() + "') is not valid.");
174  }
175  current->setCosts(costs);
176  return;
177  }
178  // add the route when it's new
179  if (myNewRoute) {
180  myAlternatives.push_back(current);
181  }
182  // recompute the costs and (when a new route was added) scale the probabilities
183  const SUMOReal scale = SUMOReal(myAlternatives.size() - 1) / SUMOReal(myAlternatives.size());
184  for (std::vector<RORoute*>::iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) {
185  RORoute* alt = *i;
186  // recompute the costs for all routes
187  const SUMOReal newCosts = router.recomputeCosts(alt->getEdgeVector(), veh, begin);
188  if (newCosts < 0.) {
189  throw ProcessError("Route '" + current->getID() + "' (vehicle '" + veh->getID() + "') is not valid.");
190  }
191  assert(myAlternatives.size() != 0);
192  if (myNewRoute) {
193  if (*i == current) {
194  // set initial probability and costs
195  alt->setProbability((SUMOReal)(1.0 / (SUMOReal) myAlternatives.size()));
196  alt->setCosts(newCosts);
197  } else {
198  // rescale probs for all others
199  alt->setProbability(alt->getProbability() * scale);
200  }
201  }
203  }
204  assert(myAlternatives.size() != 0);
206  if (!ROCostCalculator::getCalculator().keepRoutes()) {
207  // remove with probability of 0 (not mentioned in Gawron)
208  for (std::vector<RORoute*>::iterator i = myAlternatives.begin(); i != myAlternatives.end();) {
209  if ((*i)->getProbability() == 0) {
210  delete *i;
211  i = myAlternatives.erase(i);
212  } else {
213  i++;
214  }
215  }
216  }
218  // only keep the routes with highest probability
219  sort(myAlternatives.begin(), myAlternatives.end(), ComparatorProbability());
220  for (std::vector<RORoute*>::iterator i = myAlternatives.begin() + ROCostCalculator::getCalculator().getMaxRouteNumber(); i != myAlternatives.end(); i++) {
221  delete *i;
222  }
224  // rescale probabilities
225  SUMOReal newSum = 0;
226  for (std::vector<RORoute*>::iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) {
227  newSum += (*i)->getProbability();
228  }
229  assert(newSum > 0);
230  // @note newSum may be larger than 1 for numerical reasons
231  for (std::vector<RORoute*>::iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) {
232  (*i)->setProbability((*i)->getProbability() / newSum);
233  }
234  }
235 
236  // find the route to use
237  SUMOReal chosen = RandHelper::rand();
238  int pos = 0;
239  for (std::vector<RORoute*>::iterator i = myAlternatives.begin(); i != myAlternatives.end() - 1; i++, pos++) {
240  chosen -= (*i)->getProbability();
241  if (chosen <= 0) {
242  myLastUsed = pos;
243  return;
244  }
245  }
246  myLastUsed = pos;
247 }
248 
249 
250 const ROEdge*
252  return myAlternatives[0]->getLast();
253 }
254 
255 
258  bool asAlternatives, bool withExitTimes) const {
259  if (asAlternatives) {
261  for (size_t i = 0; i != myAlternatives.size(); i++) {
262  myAlternatives[i]->writeXMLDefinition(dev, veh, true, withExitTimes);
263  }
264  dev.closeTag();
265  return dev;
266  } else {
267  return myAlternatives[myLastUsed]->writeXMLDefinition(dev, veh, false, withExitTimes);
268  }
269 }
270 
271 
272 RORouteDef*
273 RORouteDef::copyOrigDest(const std::string& id) const {
274  RORouteDef* result = new RORouteDef(id, 0, true);
275  RORoute* route = myAlternatives[0];
276  RGBColor* col = route->getColor() != 0 ? new RGBColor(*route->getColor()) : 0;
277  std::vector<const ROEdge*> edges;
278  edges.push_back(route->getFirst());
279  edges.push_back(route->getLast());
280  result->addLoadedAlternative(new RORoute(id, 0, 1, edges, col));
281  return result;
282 }
283 
284 
285 RORouteDef*
286 RORouteDef::copy(const std::string& id) const {
287  RORouteDef* result = new RORouteDef(id, 0, myTryRepair);
288  for (std::vector<RORoute*>::const_iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) {
289  RORoute* route = *i;
290  RGBColor* col = route->getColor() != 0 ? new RGBColor(*route->getColor()) : 0;
291  result->addLoadedAlternative(new RORoute(id, 0, 1, route->getEdgeVector(), col));
292  }
293  return result;
294 }
295 
296 
297 SUMOReal
299  SUMOReal sum = 0.;
300  for (std::vector<RORoute*>::const_iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) {
301  sum += (*i)->getProbability();
302  }
303  return sum;
304 }
305 
306 
307 /****************************************************************************/