Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
ROMAAssignments.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-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// Assignment methods
21/****************************************************************************/
22#include <config.h>
23
24#include <vector>
25#include <algorithm>
30#include <router/ROEdge.h>
31#include <router/RONet.h>
32#include <router/RORoute.h>
33#include <od/ODMatrix.h>
34#include "ROMAEdge.h"
35#include "ROMAAssignments.h"
36
37
38// ===========================================================================
39// static member variables
40// ===========================================================================
41std::map<const ROEdge* const, double> ROMAAssignments::myPenalties;
42
43
44// ===========================================================================
45// method definitions
46// ===========================================================================
47
48ROMAAssignments::ROMAAssignments(const SUMOTime begin, const SUMOTime end, const bool additiveTraffic,
49 const double adaptionFactor, const int maxAlternatives, const bool defaultCapacities,
51 OutputDevice* netloadOutput)
52 : myBegin(begin), myEnd(end), myAdditiveTraffic(additiveTraffic), myAdaptionFactor(adaptionFactor),
53 myMaxAlternatives(maxAlternatives), myUseDefaultCapacities(defaultCapacities),
54 myNet(net), myMatrix(matrix), myRouter(router), myNetloadOutput(netloadOutput) {
56}
57
58
62
63// based on the definitions in PTV-Validate and in the VISUM-Cologne network
64double
66 if (edge->isTazConnector()) {
67 return 0;
68 }
69 const int roadClass = myUseDefaultCapacities ? -1 : -edge->getPriority();
70 // TODO: differ road class 1 from the unknown road class 1!!!
71 if (edge->getNumLanes() == 0) {
72 // TAZ have no cost
73 return 0;
74 } else if (roadClass == 0 || roadClass == 1) {
75 return edge->getNumLanes() * 2000.; //CR13 in table.py
76 } else if (roadClass == 2 && edge->getSpeedLimit() <= 11.) {
77 return edge->getNumLanes() * 1333.33; //CR5 in table.py
78 } else if (roadClass == 2 && edge->getSpeedLimit() > 11. && edge->getSpeedLimit() <= 16.) {
79 return edge->getNumLanes() * 1500.; //CR3 in table.py
80 } else if (roadClass == 2 && edge->getSpeedLimit() > 16.) {
81 return edge->getNumLanes() * 2000.; //CR13 in table.py
82 } else if (roadClass == 3 && edge->getSpeedLimit() <= 11.) {
83 return edge->getNumLanes() * 800.; //CR5 in table.py
84 } else if (roadClass == 3 && edge->getSpeedLimit() > 11. && edge->getSpeedLimit() <= 13.) {
85 return edge->getNumLanes() * 875.; //CR5 in table.py
86 } else if (roadClass == 3 && edge->getSpeedLimit() > 13. && edge->getSpeedLimit() <= 16.) {
87 return edge->getNumLanes() * 1500.; //CR4 in table.py
88 } else if (roadClass == 3 && edge->getSpeedLimit() > 16.) {
89 return edge->getNumLanes() * 1800.; //CR13 in table.py
90 } else if ((roadClass >= 4 || roadClass == -1) && edge->getSpeedLimit() <= 5.) {
91 return edge->getNumLanes() * 200.; //CR7 in table.py
92 } else if ((roadClass >= 4 || roadClass == -1) && edge->getSpeedLimit() > 5. && edge->getSpeedLimit() <= 7.) {
93 return edge->getNumLanes() * 412.5; //CR7 in table.py
94 } else if ((roadClass >= 4 || roadClass == -1) && edge->getSpeedLimit() > 7. && edge->getSpeedLimit() <= 9.) {
95 return edge->getNumLanes() * 600.; //CR6 in table.py
96 } else if ((roadClass >= 4 || roadClass == -1) && edge->getSpeedLimit() > 9. && edge->getSpeedLimit() <= 11.) {
97 return edge->getNumLanes() * 800.; //CR5 in table.py
98 } else if ((roadClass >= 4 || roadClass == -1) && edge->getSpeedLimit() > 11. && edge->getSpeedLimit() <= 13.) {
99 return edge->getNumLanes() * 1125.; //CR5 in table.py
100 } else if ((roadClass >= 4 || roadClass == -1) && edge->getSpeedLimit() > 13. && edge->getSpeedLimit() <= 16.) {
101 return edge->getNumLanes() * 1583.; //CR4 in table.py
102 } else if ((roadClass >= 4 || roadClass == -1) && edge->getSpeedLimit() > 16. && edge->getSpeedLimit() <= 18.) {
103 return edge->getNumLanes() * 1100.; //CR3 in table.py
104 } else if ((roadClass >= 4 || roadClass == -1) && edge->getSpeedLimit() > 18. && edge->getSpeedLimit() <= 22.) {
105 return edge->getNumLanes() * 1200.; //CR3 in table.py
106 } else if ((roadClass >= 4 || roadClass == -1) && edge->getSpeedLimit() > 22. && edge->getSpeedLimit() <= 26.) {
107 return edge->getNumLanes() * 1300.; //CR3 in table.py
108 } else if ((roadClass >= 4 || roadClass == -1) && edge->getSpeedLimit() > 26.) {
109 return edge->getNumLanes() * 1400.; //CR3 in table.py
110 }
111 return edge->getNumLanes() * 800.; //CR5 in table.py
112}
113
114
115// based on the definitions in PTV-Validate and in the VISUM-Cologne network
116double
117ROMAAssignments::capacityConstraintFunction(const ROEdge* edge, const double flow) const {
118 if (edge->isTazConnector()) {
119 return 0;
120 }
121 const int roadClass = myUseDefaultCapacities ? -1 : -edge->getPriority();
122 const double capacity = getCapacity(edge);
123 // TODO: differ road class 1 from the unknown road class 1!!!
124 if (edge->getNumLanes() == 0) {
125 // TAZ have no cost
126 return 0;
127 } else if (roadClass == 0 || roadClass == 1) {
128 return edge->getLength() / edge->getSpeedLimit() * (1. + 1.*(flow / (capacity * 1.3)) * 2.); //CR13 in table.py
129 } else if (roadClass == 2 && edge->getSpeedLimit() <= 11.) {
130 return edge->getLength() / edge->getSpeedLimit() * (1. + 1.*(flow / (capacity * 0.9)) * 3.); //CR5 in table.py
131 } else if (roadClass == 2 && edge->getSpeedLimit() > 11. && edge->getSpeedLimit() <= 16.) {
132 return edge->getLength() / edge->getSpeedLimit() * (1. + 1.*(flow / (capacity * 1.)) * 2.); //CR3 in table.py
133 } else if (roadClass == 2 && edge->getSpeedLimit() > 16.) {
134 return edge->getLength() / edge->getSpeedLimit() * (1. + 1.*(flow / (capacity * 1.3)) * 2.); //CR13 in table.py
135 } else if (roadClass == 3 && edge->getSpeedLimit() <= 11.) {
136 return edge->getLength() / edge->getSpeedLimit() * (1. + 1.*(flow / (capacity * 0.9)) * 3.); //CR5 in table.py
137 } else if (roadClass == 3 && edge->getSpeedLimit() > 11. && edge->getSpeedLimit() <= 13.) {
138 return edge->getLength() / edge->getSpeedLimit() * (1. + 1.*(flow / (capacity * 0.9)) * 3.); //CR5 in table.py
139 } else if (roadClass == 3 && edge->getSpeedLimit() > 13. && edge->getSpeedLimit() <= 16.) {
140 return edge->getLength() / edge->getSpeedLimit() * (1. + 1.7 * (flow / (capacity * 1.)) * 2.); //CR4 in table.py
141 } else if (roadClass == 3 && edge->getSpeedLimit() > 16.) {
142 return edge->getLength() / edge->getSpeedLimit() * (1. + 1.*(flow / (capacity * 1.3)) * 2.); //CR13 in table.py
143 } else if ((roadClass >= 4 || roadClass == -1) && edge->getSpeedLimit() <= 5.) {
144 return edge->getLength() / edge->getSpeedLimit() * (1. + 1.*(flow / (capacity * 0.5)) * 3.); //CR7 in table.py
145 } else if ((roadClass >= 4 || roadClass == -1) && edge->getSpeedLimit() > 5. && edge->getSpeedLimit() <= 7.) {
146 return edge->getLength() / edge->getSpeedLimit() * (1. + 1.*(flow / (capacity * 0.5)) * 3.); //CR7 in table.py
147 } else if ((roadClass >= 4 || roadClass == -1) && edge->getSpeedLimit() > 7. && edge->getSpeedLimit() <= 9.) {
148 return edge->getLength() / edge->getSpeedLimit() * (1. + 1.*(flow / (capacity * 0.8)) * 3.); //CR6 in table.py
149 } else if ((roadClass >= 4 || roadClass == -1) && edge->getSpeedLimit() > 9. && edge->getSpeedLimit() <= 11.) {
150 return edge->getLength() / edge->getSpeedLimit() * (1. + 1.*(flow / (capacity * 0.9)) * 3.); //CR5 in table.py
151 } else if ((roadClass >= 4 || roadClass == -1) && edge->getSpeedLimit() > 11. && edge->getSpeedLimit() <= 13.) {
152 return edge->getLength() / edge->getSpeedLimit() * (1. + 1.*(flow / (capacity * 0.9)) * 3.); //CR5 in table.py
153 } else if ((roadClass >= 4 || roadClass == -1) && edge->getSpeedLimit() > 13. && edge->getSpeedLimit() <= 16.) {
154 return edge->getLength() / edge->getSpeedLimit() * (1. + 1.7 * (flow / (capacity * 1.)) * 2.); //CR4 in table.py
155 } else if ((roadClass >= 4 || roadClass == -1) && edge->getSpeedLimit() > 16. && edge->getSpeedLimit() <= 18.) {
156 return edge->getLength() / edge->getSpeedLimit() * (1. + 1.*(flow / (capacity * 1.)) * 2.); //CR3 in table.py
157 } else if ((roadClass >= 4 || roadClass == -1) && edge->getSpeedLimit() > 18. && edge->getSpeedLimit() <= 22.) {
158 return edge->getLength() / edge->getSpeedLimit() * (1. + 1.*(flow / (capacity * 1.)) * 2.); //CR3 in table.py
159 } else if ((roadClass >= 4 || roadClass == -1) && edge->getSpeedLimit() > 22. && edge->getSpeedLimit() <= 26.) {
160 return edge->getLength() / edge->getSpeedLimit() * (1. + 1.*(flow / (capacity * 1.)) * 2.); //CR3 in table.py
161 } else if ((roadClass >= 4 || roadClass == -1) && edge->getSpeedLimit() > 26.) {
162 return edge->getLength() / edge->getSpeedLimit() * (1. + 1.*(flow / (capacity * 1.)) * 2.); //CR3 in table.py
163 }
164 return edge->getLength() / edge->getSpeedLimit() * (1. + 1.*(flow / (capacity * 0.9)) * 3.); //CR5 in table.py
165}
166
167
168bool
169ROMAAssignments::addRoute(const ConstROEdgeVector& edges, std::vector<RORoute*>& paths, std::string routeId, double prob) {
170 std::vector<RORoute*>::iterator p;
171 for (p = paths.begin(); p != paths.end(); p++) {
172 if (edges == (*p)->getEdgeVector()) {
173 break;
174 }
175 }
176 if (p == paths.end()) {
177 paths.push_back(new RORoute(routeId, 0., prob, edges, nullptr, std::vector<SUMOVehicleParameter::Stop>()));
178 return true;
179 }
180 (*p)->addProbability(prob);
181 std::iter_swap(paths.end() - 1, p);
182 return false;
183}
184
185
187ROMAAssignments::computePath(ODCell* cell, const SUMOTime time, const double probability, SUMOAbstractRouter<ROEdge, ROVehicle>* router, bool setBulkMode) {
188 const ROEdge* const from = myNet.getEdge(cell->origin + (cell->originIsEdge ? "" : "-source"));
189 if (from == nullptr) {
190 throw ProcessError(TLF("Unknown origin '%'.", cell->origin));
191 }
192 const ROEdge* const to = myNet.getEdge(cell->destination + (cell->destinationIsEdge ? "" : "-sink"));
193 if (to == nullptr) {
194 throw ProcessError(TLF("Unknown destination '%'.", cell->destination));
195 }
196 ConstROEdgeVector edges;
197 if (router == nullptr) {
198 router = &myRouter;
199 }
200 if (myMaxAlternatives > 0 && (int)cell->pathsVector.size() < myMaxAlternatives) {
201 router->compute(from, to, myDefaultVehicle, time, edges);
202 if (setBulkMode) {
203 router->setBulkMode(true);
204 }
205 if (addRoute(edges, cell->pathsVector, cell->origin + cell->destination + toString(cell->pathsVector.size()), probability)) {
206 return edges;
207 }
208 } else {
209 double minCost = std::numeric_limits<double>::max();
210 RORoute* minRoute = nullptr;
211 for (RORoute* const p : cell->pathsVector) {
212 const double cost = router->recomputeCosts(edges, myDefaultVehicle, time);
213 if (cost < minCost) {
214 minCost = cost;
215 minRoute = p;
216 }
217 }
218 minRoute->addProbability(probability);
219 }
220 return ConstROEdgeVector();
221}
222
223
224void
225ROMAAssignments::getKPaths(const int kPaths, const double penalty) {
226 for (ODCell* const c : myMatrix.getCells()) {
227 myPenalties.clear();
228 for (int k = 0; k < kPaths; k++) {
229 for (const ROEdge* const e : computePath(c)) {
230 myPenalties[e] += penalty;
231 }
232 }
233 }
234 myPenalties.clear();
235}
236
237
238void
240 const double begin = STEPS2TIME(MIN2(myBegin, myMatrix.getCells().front()->begin));
241 for (std::map<std::string, ROEdge*>::const_iterator i = myNet.getEdgeMap().begin(); i != myNet.getEdgeMap().end(); ++i) {
242 ROMAEdge* edge = static_cast<ROMAEdge*>(i->second);
243 edge->setFlow(begin, STEPS2TIME(myEnd), 0.);
244 edge->setHelpFlow(begin, STEPS2TIME(myEnd), 0.);
245 }
246}
247
248
249void
251 if (myNetloadOutput != nullptr) {
253 for (std::map<std::string, ROEdge*>::const_iterator i = myNet.getEdgeMap().begin(); i != myNet.getEdgeMap().end(); ++i) {
254 ROMAEdge* edge = static_cast<ROMAEdge*>(i->second);
255 if (edge->getFunction() == SumoXMLEdgeFunc::NORMAL) {
257 const double traveltime = edge->getTravelTime(getDefaultVehicle(), STEPS2TIME(begin));
258 const double speed = edge->getLength() / traveltime;
259 const double flow = edge->getFlow(STEPS2TIME(begin));
260 const double timeGap = STEPS2TIME(end - begin) / flow;
261 const double spaceGap = timeGap * speed;
262 const double density = 1000.0 / spaceGap;
263 const double laneDensity = density / edge->getNumLanes();
270 myNetloadOutput->writeAttr("flowCapacityRatio", 100. * flow / getCapacity(edge));
272 }
273 }
275 }
276}
277
278
279void
280ROMAAssignments::incremental(const int numIter, const bool verbose) {
281 SUMOTime lastBegin = -1;
282 std::vector<int> intervals;
283 int count = 0;
284 for (const ODCell* const c : myMatrix.getCells()) {
285 if (c->begin != lastBegin) {
286 intervals.push_back(count);
287 lastBegin = c->begin;
288 }
289 count++;
290 }
291 lastBegin = -1;
292 for (std::vector<int>::const_iterator offset = intervals.begin(); offset != intervals.end(); offset++) {
293 std::vector<ODCell*>::const_iterator firstCell = myMatrix.getCells().begin() + (*offset);
294 std::vector<ODCell*>::const_iterator lastCell = myMatrix.getCells().end();
295 if (offset != intervals.end() - 1) {
296 lastCell = myMatrix.getCells().begin() + (*(offset + 1));
297 }
298 const SUMOTime intervalStart = (*firstCell)->begin;
299 if (verbose) {
300 WRITE_MESSAGE(" starting interval " + time2string(intervalStart));
301 }
302 std::map<const ROMAEdge*, double> loadedTravelTimes;
303 for (std::map<std::string, ROEdge*>::const_iterator i = myNet.getEdgeMap().begin(); i != myNet.getEdgeMap().end(); ++i) {
304 ROMAEdge* edge = static_cast<ROMAEdge*>(i->second);
305 if (edge->hasLoadedTravelTime(STEPS2TIME(intervalStart))) {
306 loadedTravelTimes[edge] = edge->getTravelTime(myDefaultVehicle, STEPS2TIME(intervalStart));
307 }
308 }
309 if (loadedTravelTimes.empty()) {
310 // we don't have loaded travel times for this interval but we may have set ourselves some for the interval before but no need to warn
312 }
313 for (int t = 0; t < numIter; t++) {
314 if (verbose) {
315 WRITE_MESSAGE(" starting iteration " + toString(t));
316 }
317 std::string lastOrigin = "";
318 int workerIndex = 0;
319 for (std::vector<ODCell*>::const_iterator i = firstCell; i != lastCell; i++) {
320 ODCell* const c = *i;
321 const double linkFlow = c->vehicleNumber / numIter;
322 const SUMOTime begin = myAdditiveTraffic ? myBegin : c->begin;
323#ifdef HAVE_FOX
324 if (myNet.getThreadPool().size() > 0) {
325 if (lastOrigin != c->origin) {
326 workerIndex++;
327 if (workerIndex == myNet.getThreadPool().size()) {
328 workerIndex = 0;
329 }
330 myNet.getThreadPool().add(new RONet::BulkmodeTask(false), workerIndex);
331 lastOrigin = c->origin;
332 myNet.getThreadPool().add(new RoutingTask(*this, c, begin, linkFlow), workerIndex);
333 } else {
334 myNet.getThreadPool().add(new RoutingTask(*this, c, begin, linkFlow), workerIndex);
335 }
336 continue;
337 }
338#endif
339 if (lastOrigin != c->origin) {
340 myRouter.setBulkMode(false);
341 lastOrigin = c->origin;
342 }
343 computePath(c, begin, linkFlow, &myRouter, true);
344 }
345#ifdef HAVE_FOX
346 if (myNet.getThreadPool().size() > 0) {
347 myNet.getThreadPool().waitAll();
348 }
349#endif
350 for (std::vector<ODCell*>::const_iterator i = firstCell; i != lastCell; i++) {
351 ODCell* const c = *i;
352 const double linkFlow = c->vehicleNumber / numIter;
353 const SUMOTime begin = myAdditiveTraffic ? myBegin : c->begin;
354 const SUMOTime end = myAdditiveTraffic ? myEnd : c->end;
355 const double intervalLengthInHours = STEPS2TIME(end - begin) / 3600.;
356 const ConstROEdgeVector& edges = c->pathsVector.back()->getEdgeVector();
357 for (ConstROEdgeVector::const_iterator e = edges.begin(); e != edges.end(); e++) {
358 ROMAEdge* edge = static_cast<ROMAEdge*>(myNet.getEdge((*e)->getID()));
359 const double newFlow = edge->getFlow(STEPS2TIME(begin)) + linkFlow;
360 edge->setFlow(STEPS2TIME(begin), STEPS2TIME(end), newFlow);
361 double travelTime = capacityConstraintFunction(edge, newFlow / intervalLengthInHours);
362 if (lastBegin >= 0 && myAdaptionFactor > 0.) {
363 if (loadedTravelTimes.count(edge) != 0) {
364 travelTime = loadedTravelTimes[edge] * myAdaptionFactor + (1. - myAdaptionFactor) * travelTime;
365 } else {
366 travelTime = edge->getTravelTime(myDefaultVehicle, STEPS2TIME(lastBegin)) * myAdaptionFactor + (1. - myAdaptionFactor) * travelTime;
367 }
368 }
369 edge->addTravelTime(travelTime, STEPS2TIME(begin), STEPS2TIME(end));
370 }
371 }
373 }
374 writeInterval(intervalStart, (*(lastCell - 1))->end);
375 lastBegin = intervalStart;
376 }
377}
378
379
380void
381ROMAAssignments::sue(const int maxOuterIteration, const int maxInnerIteration, const int kPaths, const double penalty, const double tolerance, const std::string /* routeChoiceMethod */) {
382 getKPaths(kPaths, penalty);
383 std::map<const SUMOTime, SUMOTime> intervals;
384 if (myAdditiveTraffic) {
385 intervals[myBegin] = myEnd;
386 } else {
387 for (const ODCell* const c : myMatrix.getCells()) {
388 intervals[c->begin] = c->end;
389 }
390 }
391 for (int outer = 0; outer < maxOuterIteration; outer++) {
392 for (int inner = 0; inner < maxInnerIteration; inner++) {
393 for (const ODCell* const c : myMatrix.getCells()) {
394 const SUMOTime begin = myAdditiveTraffic ? myBegin : c->begin;
395 const SUMOTime end = myAdditiveTraffic ? myEnd : c->end;
396 // update path cost
397 for (std::vector<RORoute*>::const_iterator j = c->pathsVector.begin(); j != c->pathsVector.end(); ++j) {
398 RORoute* r = *j;
400 // std::cout << std::setprecision(20) << r->getID() << ":" << r->getCosts() << std::endl;
401 }
402 // calculate route utilities and probabilities
403 RouteCostCalculator<RORoute, ROEdge, ROVehicle>::getCalculator().calculateProbabilities(c->pathsVector, myDefaultVehicle, 0);
404 // calculate route flows
405 for (std::vector<RORoute*>::const_iterator j = c->pathsVector.begin(); j != c->pathsVector.end(); ++j) {
406 RORoute* r = *j;
407 const double pathFlow = r->getProbability() * c->vehicleNumber;
408 // assign edge flow deltas
409 for (ConstROEdgeVector::const_iterator e = r->getEdgeVector().begin(); e != r->getEdgeVector().end(); e++) {
410 ROMAEdge* edge = static_cast<ROMAEdge*>(myNet.getEdge((*e)->getID()));
411 edge->setHelpFlow(STEPS2TIME(begin), STEPS2TIME(end), edge->getHelpFlow(STEPS2TIME(begin)) + pathFlow);
412 }
413 }
414 }
415 // calculate new edge flows and check for stability
416 int unstableEdges = 0;
417 for (const auto& it : intervals) {
418 const double intervalLengthInHours = STEPS2TIME(it.second - it.first) / 3600.;
419 const double intBegin = STEPS2TIME(it.first);
420 const double intEnd = STEPS2TIME(it.second);
421 for (std::map<std::string, ROEdge*>::const_iterator e = myNet.getEdgeMap().begin(); e != myNet.getEdgeMap().end(); ++e) {
422 ROMAEdge* edge = static_cast<ROMAEdge*>(e->second);
423 const double oldFlow = edge->getFlow(intBegin);
424 double newFlow = oldFlow;
425 if (inner == 0 && outer == 0) {
426 newFlow += edge->getHelpFlow(intBegin);
427 } else {
428 newFlow += (edge->getHelpFlow(intBegin) - oldFlow) / (inner + 1);
429 }
430 // if not lohse:
431 if (newFlow > 0.) {
432 if (fabs(newFlow - oldFlow) / newFlow > tolerance) {
433 unstableEdges++;
434 }
435 } else if (newFlow == 0.) {
436 if (oldFlow != 0. && (fabs(newFlow - oldFlow) / oldFlow > tolerance)) {
437 unstableEdges++;
438 }
439 } else { // newFlow < 0.
440 unstableEdges++;
441 newFlow = 0.;
442 }
443 edge->setFlow(intBegin, intEnd, newFlow);
444 const double travelTime = capacityConstraintFunction(edge, newFlow / intervalLengthInHours);
445 edge->addTravelTime(travelTime, intBegin, intEnd);
446 edge->setHelpFlow(intBegin, intEnd, 0.);
447 }
448 }
449 // if stable break
450 if (unstableEdges == 0) {
451 break;
452 }
453 // additional stability check from python script: if notstable < math.ceil(net.geteffEdgeCounts()*0.005) or notstable < 3: stable = True
454 }
455 // check for a new route, if none available, break
456 // several modifications about when a route is new and when to break are in the original script
457 bool newRoute = false;
458 for (ODCell* const c : myMatrix.getCells()) {
459 newRoute |= !computePath(c).empty();
460 }
461 if (!newRoute) {
462 break;
463 }
464 }
465 // final round of assignment
466 for (const ODCell* const c : myMatrix.getCells()) {
467 // update path cost
468 for (std::vector<RORoute*>::const_iterator j = c->pathsVector.begin(); j != c->pathsVector.end(); ++j) {
469 RORoute* r = *j;
471 }
472 // calculate route utilities and probabilities
473 RouteCostCalculator<RORoute, ROEdge, ROVehicle>::getCalculator().calculateProbabilities(c->pathsVector, myDefaultVehicle, 0);
474 // calculate route flows
475 for (std::vector<RORoute*>::const_iterator j = c->pathsVector.begin(); j != c->pathsVector.end(); ++j) {
476 RORoute* r = *j;
477 r->setProbability(r->getProbability() * c->vehicleNumber);
478 }
479 }
480 for (const auto& it : intervals) {
481 writeInterval(it.first, it.second);
482 }
483}
484
485
486double
487ROMAAssignments::getPenalizedEffort(const ROEdge* const e, const ROVehicle* const v, double t) {
488 const std::map<const ROEdge* const, double>::const_iterator i = myPenalties.find(e);
489 return i == myPenalties.end() ? e->getEffort(v, t) : e->getEffort(v, t) + i->second;
490}
491
492
493double
494ROMAAssignments::getPenalizedTT(const ROEdge* const e, const ROVehicle* const v, double t) {
495 const std::map<const ROEdge* const, double>::const_iterator i = myPenalties.find(e);
496 return i == myPenalties.end() ? e->getTravelTime(v, t) : e->getTravelTime(v, t) + i->second;
497}
498
499
500double
501ROMAAssignments::getTravelTime(const ROEdge* const e, const ROVehicle* const v, double t) {
502 return e->getTravelTime(v, t);
503}
504
505
506#ifdef HAVE_FOX
507// ---------------------------------------------------------------------------
508// ROMAAssignments::RoutingTask-methods
509// ---------------------------------------------------------------------------
510void
511ROMAAssignments::RoutingTask::run(MFXWorkerThread* context) {
512 myAssign.computePath(myCell, myBegin, myLinkFlow, &static_cast<RONet::WorkerThread*>(context)->getVehicleRouter(SVC_IGNORING), mySetBulkMode);
513}
514#endif
long long int SUMOTime
Definition GUI.h:36
#define WRITE_MESSAGE(msg)
Definition MsgHandler.h:297
#define TLF(string,...)
Definition MsgHandler.h:317
std::vector< const ROEdge * > ConstROEdgeVector
Definition ROEdge.h:54
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition SUMOTime.cpp:69
#define STEPS2TIME(x)
Definition SUMOTime.h:55
const std::string DEFAULT_VTYPE_ID
@ SVC_IGNORING
vehicles ignoring classes
@ SUMO_TAG_INTERVAL
an aggreagated-output interval
@ SUMO_TAG_EDGE
begin/end of the description of an edge
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_TRAVELTIME
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_SPEEDREL
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_ENTERED
@ SUMO_ATTR_ID
@ SUMO_ATTR_LANEDENSITY
@ SUMO_ATTR_DENSITY
T MIN2(T a, T b)
Definition StdDefs.h:76
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
A thread repeatingly calculating incoming tasks.
const std::string & getID() const
Returns the id.
Definition Named.h:74
IDMap::const_iterator begin() const
Returns a reference to the begin iterator for the internal map.
IDMap::const_iterator end() const
Returns a reference to the end iterator for the internal map.
An O/D (origin/destination) matrix.
Definition ODMatrix.h:68
const std::vector< ODCell * > & getCells()
Definition ODMatrix.h:245
Static storage of an output device and its base (abstract) implementation.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
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 hasLoadedTravelTime(double time) const
Returns whether a travel time for this edge was loaded.
Definition ROEdge.cpp:184
int getNumLanes() const
Returns the number of lanes this edge has.
Definition ROEdge.h:260
int getPriority() const
get edge priority (road class)
Definition ROEdge.h:508
bool isTazConnector() const
Definition ROEdge.h:168
double getSpeedLimit() const
Returns the speed allowed on this edge.
Definition ROEdge.h:234
static void disableTimelineWarning()
Definition ROEdge.h:500
SumoXMLEdgeFunc getFunction() const
Returns the function of the edge.
Definition ROEdge.h:203
double getTravelTime(const ROVehicle *const veh, double time) const
Returns the travel time for this edge.
Definition ROEdge.cpp:190
void addTravelTime(double value, double timeBegin, double timeEnd)
Adds a travel time value.
Definition ROEdge.cpp:147
double getEffort(const ROVehicle *const veh, double time) const
Returns the effort for this edge.
Definition ROEdge.cpp:154
double getLength() const
Returns the length of the edge.
Definition ROEdge.h:219
ROVehicle * getDefaultVehicle() const
const ConstROEdgeVector computePath(ODCell *cell, const SUMOTime time=0, const double probability=0., SUMOAbstractRouter< ROEdge, ROVehicle > *router=nullptr, bool setBulkMode=false)
const double myAdaptionFactor
void sue(const int maxOuterIteration, const int maxInnerIteration, const int kPaths, const double penalty, const double tolerance, const std::string routeChoiceMethod)
void getKPaths(const int kPaths, const double penalty)
get the k shortest paths
static double getPenalizedEffort(const ROEdge *const e, const ROVehicle *const v, double t)
Returns the effort to pass an edge including penalties.
void incremental(const int numIter, const bool verbose)
double capacityConstraintFunction(const ROEdge *edge, const double flow) const
double getCapacity(const ROEdge *edge) const
const bool myAdditiveTraffic
const int myMaxAlternatives
void writeInterval(const SUMOTime begin, const SUMOTime end)
ROMAAssignments(const SUMOTime begin, const SUMOTime end, const bool additiveTraffic, const double adaptionFactor, const int maxAlternatives, const bool defaultCapacities, RONet &net, ODMatrix &matrix, SUMOAbstractRouter< ROEdge, ROVehicle > &router, OutputDevice *netloadOutput)
Constructor.
ROVehicle * myDefaultVehicle
const SUMOTime myEnd
OutputDevice *const myNetloadOutput
static double getPenalizedTT(const ROEdge *const e, const ROVehicle *const v, double t)
Returns the traveltime on an edge including penalties.
static double getTravelTime(const ROEdge *const e, const ROVehicle *const v, double t)
Returns the traveltime on an edge without penalties.
static std::map< const ROEdge *const, double > myPenalties
SUMOAbstractRouter< ROEdge, ROVehicle > & myRouter
const bool myUseDefaultCapacities
bool addRoute(const ConstROEdgeVector &edges, std::vector< RORoute * > &paths, std::string routeId, double prob)
add a route and check for duplicates
const SUMOTime myBegin
~ROMAAssignments()
Destructor.
A basic edge for routing applications.
Definition ROMAEdge.h:55
double getHelpFlow(const double time) const
Definition ROMAEdge.h:91
void setFlow(const double begin, const double end, const double flow)
Definition ROMAEdge.h:79
double getFlow(const double time) const
Definition ROMAEdge.h:83
void setHelpFlow(const double begin, const double end, const double flow)
Definition ROMAEdge.h:87
The router's network representation.
Definition RONet.h:62
SUMOVTypeParameter * getVehicleTypeSecure(const std::string &id)
Retrieves the named vehicle type.
Definition RONet.cpp:364
ROEdge * getEdge(const std::string &name) const
Retrieves an edge from the network.
Definition RONet.h:157
const NamedObjectCont< ROEdge * > & getEdgeMap() const
Definition RONet.h:422
A complete router's route.
Definition RORoute.h:52
void setProbability(double prob)
Sets the probability of the route.
Definition RORoute.cpp:70
double getProbability() const
Returns the probability the driver will take this route with.
Definition RORoute.h:120
void addProbability(double prob)
add additional vehicles/probability
Definition RORoute.cpp:96
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
static RouteCostCalculator< R, E, V > & getCalculator()
virtual void setBulkMode(const bool mode)
virtual void reset(const V *const vehicle)
reset internal caches, used by CHRouter
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
Structure representing possible vehicle parameter.
A single O/D-matrix cell.
Definition ODCell.h:49
std::string destination
Name of the destination district.
Definition ODCell.h:63
std::string origin
Name of the origin district.
Definition ODCell.h:60
std::vector< RORoute * > pathsVector
the list of paths / routes
Definition ODCell.h:69
double vehicleNumber
The number of vehicles.
Definition ODCell.h:51
bool originIsEdge
the origin "district" is an edge id
Definition ODCell.h:76
SUMOTime end
The end time this cell describes.
Definition ODCell.h:57
SUMOTime begin
The begin time this cell describes.
Definition ODCell.h:54
bool destinationIsEdge
the destination "district" is an edge id
Definition ODCell.h:79