SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RORouteDef_Alternatives.cpp
Go to the documentation of this file.
1 /****************************************************************************/
8 // A route with alternative routes
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 
34 #include "ROHelper.h"
35 #include "ROEdge.h"
36 #include "RORouteDef.h"
37 #include "ROVehicle.h"
38 #include "ROCostCalculator.h"
40 
41 #ifdef CHECK_MEMORY_LEAKS
42 #include <foreign/nvwa/debug_new.h>
43 #endif // CHECK_MEMORY_LEAKS
44 
45 
46 // ===========================================================================
47 // method definitions
48 // ===========================================================================
50  unsigned int lastUsed,
51  const int maxRoutes, const bool keepRoutes, const bool skipRouteCalculation)
52  : RORouteDef(id, 0), myLastUsed((int) lastUsed),
53  myMaxRouteNumber(maxRoutes), myKeepRoutes(keepRoutes),
54  mySkipRouteCalculation(skipRouteCalculation) {
55 }
56 
57 
59  for (AlternativesVector::iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) {
60  delete *i;
61  }
62 }
63 
64 
65 void
67  myAlternatives.push_back(alt);
68 }
69 
70 
71 void
73  SUMOTime begin, const ROVehicle& veh) const {
75  myLastUsed = 0;
76  myNewRoute = false;
78  return;
79  }
80  // recompute duration of the last route used
81  // build a new route to test whether it is better
82  std::vector<const ROEdge*> edges;
83  router.compute(myAlternatives[0]->getFirst(), myAlternatives[0]->getLast(), &veh, begin, edges);
84  RORoute* opt = new RORoute(myID, 0, 1, edges, copyColorIfGiven());
85  const SUMOReal costs = router.recomputeCosts(edges, &veh, begin);
86  // check whether the same route was already used
87  myLastUsed = findRoute(opt);
88  myNewRoute = true;
89  // delete the route when it already existed
90  if (myLastUsed >= 0) {
91  delete opt;
92  myNewRoute = false;
93  myAlternatives[myLastUsed]->setCosts(costs);
95  return;
96  }
97  // return the built route
98  ROCostCalculator::getCalculator().setCosts(opt, costs, true);
99  myPrecomputed = opt;
100 }
101 
102 
103 int
105  for (unsigned int i = 0; i < myAlternatives.size(); i++) {
106  if (opt->getEdgeVector() == myAlternatives[i]->getEdgeVector()) {
107  return (int) i;
108  }
109  }
110  return -1;
111 }
112 
113 
114 void
116  const ROVehicle* const veh, RORoute* current, SUMOTime begin) {
117  // add the route when it's new
118  if (myLastUsed < 0) {
119  myAlternatives.push_back(current);
120  myLastUsed = (int) myAlternatives.size() - 1;
121  }
122  // recompute the costs and (when a new route was added) the probabilities
123  for (AlternativesVector::iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) {
124  RORoute* alt = *i;
125  // apply changes for old routes only
126  // (the costs for the current were computed already)
127  if ((*i) != current || !myNewRoute) {
128  // recompute the costs for old routes
129  const SUMOReal newCosts = router.recomputeCosts(alt->getEdgeVector(), veh, begin);
130  if (newCosts < 0.) {
131  throw ProcessError("Route '" + current->getID() + "' (vehicle '" + veh->getID() + "') is not valid.");
132  }
133  ROCostCalculator::getCalculator().setCosts(alt, newCosts);
134  }
135  assert(myAlternatives.size() != 0);
136  if (myNewRoute) {
137  if ((*i) != current) {
138  alt->setProbability(
139  alt->getProbability()
140  * SUMOReal(myAlternatives.size() - 1)
141  / SUMOReal(myAlternatives.size()));
142  } else {
143  alt->setProbability((SUMOReal)(1.0 / (SUMOReal) myAlternatives.size()));
144  }
145  }
146  }
147  assert(myAlternatives.size() != 0);
149  if (!myKeepRoutes) {
150  // remove with probability of 0 (not mentioned in Gawron)
151  for (AlternativesVector::iterator i = myAlternatives.begin(); i != myAlternatives.end();) {
152  if ((*i)->getProbability() == 0) {
153  i = myAlternatives.erase(i);
154  } else {
155  i++;
156  }
157  }
158  }
159  if (myAlternatives.size() > (unsigned)myMaxRouteNumber) {
160  // only keep the routes with highest probability
161  sort(myAlternatives.begin(), myAlternatives.end(), ComparatorProbability());
162  for (AlternativesVector::iterator i = myAlternatives.begin() + myMaxRouteNumber; i != myAlternatives.end(); i++) {
163  delete *i;
164  }
166  // rescale probabilities
167  SUMOReal newSum = 0;
168  for (AlternativesVector::iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) {
169  newSum += (*i)->getProbability();
170  }
171  assert(newSum > 0);
172  // @note newSum may be larger than 1 for numerical reasons
173  for (AlternativesVector::iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) {
174  (*i)->setProbability((*i)->getProbability() / newSum);
175  }
176  }
177 
178  // find the route to use
179  SUMOReal chosen = RandHelper::rand();
180  int pos = 0;
181  for (AlternativesVector::iterator i = myAlternatives.begin(); i != myAlternatives.end() - 1; i++, pos++) {
182  chosen = chosen - (*i)->getProbability();
183  if (chosen <= 0) {
184  myLastUsed = pos;
185  return;
186  }
187  }
188  myLastUsed = pos;
189 }
190 
191 
192 RORouteDef*
193 RORouteDef_Alternatives::copy(const std::string& id) const {
196  for (std::vector<RORoute*>::const_iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) {
197  ret->addLoadedAlternative(new RORoute(*(*i)));
198  }
199  return ret;
200 }
201 
202 
203 void
205  myLastUsed = -1;
206 }
207 
208 
209 void
211  assert(myAlternatives.size() >= 2);
212  myAlternatives.erase(myAlternatives.end() - 1);
213  myLastUsed = (int) myAlternatives.size() - 1;
214  // !!! recompute probabilities
215 }
216 
217 
220  OutputDevice& dev, const ROVehicle* const veh,
221  bool asAlternatives, bool withExitTimes) const {
222  // (optional) alternatives header
223  if (asAlternatives) {
225  for (size_t i = 0; i != myAlternatives.size(); i++) {
226  const RORoute& alt = *(myAlternatives[i]);
228  dev.setPrecision(8);
230  dev.setPrecision();
231  if (alt.getColor() != 0) {
232  dev.writeAttr(SUMO_ATTR_COLOR, *alt.getColor());
233  } else if (myColor != 0) {
235  }
237  if (withExitTimes) {
238  std::string exitTimes;
239  SUMOReal time = STEPS2TIME(veh->getDepartureTime());
240  for (std::vector<const ROEdge*>::const_iterator i = alt.getEdgeVector().begin(); i != alt.getEdgeVector().end(); ++i) {
241  if (i != alt.getEdgeVector().begin()) {
242  exitTimes += " ";
243  }
244  time += (*i)->getTravelTime(veh, time);
245  exitTimes += toString(time);
246  }
247  dev.writeAttr("exitTimes", exitTimes);
248  }
249  dev.closeTag(true);
250  }
251  dev.closeTag();
252  return dev;
253  } else {
254  return myAlternatives[myLastUsed]->writeXMLDefinition(router, dev, veh, asAlternatives, withExitTimes);
255  }
256 }
257 
258 
259 const ROEdge*
261  return myAlternatives[0]->getLast();
262 }
263 
264 
265 
266 /****************************************************************************/