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-2026 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, StopParVector()));
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 (ROEdge* e : ROEdge::getAllEdges()) {
242 ROMAEdge* const edge = static_cast<ROMAEdge*>(e);
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 (ROEdge* e : ROEdge::getAllEdges()) {
254 const ROMAEdge* const edge = static_cast<ROMAEdge*>(e);
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 (ROEdge* e : ROEdge::getAllEdges()) {
304 const ROMAEdge* const edge = static_cast<ROMAEdge*>(e);
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#else
339 UNUSED_PARAMETER(workerIndex);
340#endif
341 if (lastOrigin != c->origin) {
342 myRouter.setBulkMode(false);
343 lastOrigin = c->origin;
344 }
345 computePath(c, begin, linkFlow, &myRouter, true);
346 }
347#ifdef HAVE_FOX
348 if (myNet.getThreadPool().size() > 0) {
349 myNet.getThreadPool().waitAll();
350 }
351#endif
352 for (std::vector<ODCell*>::const_iterator i = firstCell; i != lastCell; i++) {
353 ODCell* const c = *i;
354 const double linkFlow = c->vehicleNumber / numIter;
355 const SUMOTime begin = myAdditiveTraffic ? myBegin : c->begin;
356 const SUMOTime end = myAdditiveTraffic ? myEnd : c->end;
357 const double intervalLengthInHours = STEPS2TIME(end - begin) / 3600.;
358 const ConstROEdgeVector& edges = c->pathsVector.back()->getEdgeVector();
359 for (ConstROEdgeVector::const_iterator e = edges.begin(); e != edges.end(); e++) {
360 ROMAEdge* edge = static_cast<ROMAEdge*>(myNet.getEdge((*e)->getID()));
361 const double newFlow = edge->getFlow(STEPS2TIME(begin)) + linkFlow;
362 edge->setFlow(STEPS2TIME(begin), STEPS2TIME(end), newFlow);
363 double travelTime = capacityConstraintFunction(edge, newFlow / intervalLengthInHours);
364 if (lastBegin >= 0 && myAdaptionFactor > 0.) {
365 if (loadedTravelTimes.count(edge) != 0) {
366 travelTime = loadedTravelTimes[edge] * myAdaptionFactor + (1. - myAdaptionFactor) * travelTime;
367 } else {
368 travelTime = edge->getTravelTime(myDefaultVehicle, STEPS2TIME(lastBegin)) * myAdaptionFactor + (1. - myAdaptionFactor) * travelTime;
369 }
370 }
371 edge->addTravelTime(travelTime, STEPS2TIME(begin), STEPS2TIME(end));
372 }
373 }
375 }
376 writeInterval(intervalStart, (*(lastCell - 1))->end);
377 lastBegin = intervalStart;
378 }
379}
380
381
382void
383ROMAAssignments::sue(const int maxOuterIteration, const int maxInnerIteration, const int kPaths, const double penalty, const double tolerance, const std::string /* routeChoiceMethod */) {
384 getKPaths(kPaths, penalty);
385 std::map<const SUMOTime, SUMOTime> intervals;
386 if (myAdditiveTraffic) {
387 intervals[myBegin] = myEnd;
388 } else {
389 for (const ODCell* const c : myMatrix.getCells()) {
390 intervals[c->begin] = c->end;
391 }
392 }
393 for (int outer = 0; outer < maxOuterIteration; outer++) {
394 for (int inner = 0; inner < maxInnerIteration; inner++) {
395 for (const ODCell* const c : myMatrix.getCells()) {
396 const SUMOTime begin = myAdditiveTraffic ? myBegin : c->begin;
397 const SUMOTime end = myAdditiveTraffic ? myEnd : c->end;
398 // update path cost
399 for (std::vector<RORoute*>::const_iterator j = c->pathsVector.begin(); j != c->pathsVector.end(); ++j) {
400 RORoute* r = *j;
402 // std::cout << std::setprecision(20) << r->getID() << ":" << r->getCosts() << std::endl;
403 }
404 // calculate route utilities and probabilities
405 RouteCostCalculator<RORoute, ROEdge, ROVehicle>::getCalculator().calculateProbabilities(c->pathsVector, myDefaultVehicle, 0);
406 // calculate route flows
407 for (std::vector<RORoute*>::const_iterator j = c->pathsVector.begin(); j != c->pathsVector.end(); ++j) {
408 RORoute* r = *j;
409 const double pathFlow = r->getProbability() * c->vehicleNumber;
410 // assign edge flow deltas
411 for (ConstROEdgeVector::const_iterator e = r->getEdgeVector().begin(); e != r->getEdgeVector().end(); e++) {
412 ROMAEdge* edge = static_cast<ROMAEdge*>(myNet.getEdge((*e)->getID()));
413 edge->setHelpFlow(STEPS2TIME(begin), STEPS2TIME(end), edge->getHelpFlow(STEPS2TIME(begin)) + pathFlow);
414 }
415 }
416 }
417 // calculate new edge flows and check for stability
418 int unstableEdges = 0;
419 for (const auto& it : intervals) {
420 const double intervalLengthInHours = STEPS2TIME(it.second - it.first) / 3600.;
421 const double intBegin = STEPS2TIME(it.first);
422 const double intEnd = STEPS2TIME(it.second);
423 for (ROEdge* e : ROEdge::getAllEdges()) {
424 ROMAEdge* const edge = static_cast<ROMAEdge*>(e);
425 const double oldFlow = edge->getFlow(intBegin);
426 double newFlow = oldFlow;
427 if (inner == 0 && outer == 0) {
428 newFlow += edge->getHelpFlow(intBegin);
429 } else {
430 newFlow += (edge->getHelpFlow(intBegin) - oldFlow) / (inner + 1);
431 }
432 // if not lohse:
433 if (newFlow > 0.) {
434 if (fabs(newFlow - oldFlow) / newFlow > tolerance) {
435 unstableEdges++;
436 }
437 } else if (newFlow == 0.) {
438 if (oldFlow != 0. && (fabs(newFlow - oldFlow) / oldFlow > tolerance)) {
439 unstableEdges++;
440 }
441 } else { // newFlow < 0.
442 unstableEdges++;
443 newFlow = 0.;
444 }
445 edge->setFlow(intBegin, intEnd, newFlow);
446 const double travelTime = capacityConstraintFunction(edge, newFlow / intervalLengthInHours);
447 edge->addTravelTime(travelTime, intBegin, intEnd);
448 edge->setHelpFlow(intBegin, intEnd, 0.);
449 }
450 }
451 // if stable break
452 if (unstableEdges == 0) {
453 break;
454 }
455 // additional stability check from python script: if notstable < math.ceil(net.geteffEdgeCounts()*0.005) or notstable < 3: stable = True
456 }
457 // check for a new route, if none available, break
458 // several modifications about when a route is new and when to break are in the original script
459 bool newRoute = false;
460 for (ODCell* const c : myMatrix.getCells()) {
461 newRoute |= !computePath(c).empty();
462 }
463 if (!newRoute) {
464 break;
465 }
466 }
467 // final round of assignment
468 for (const ODCell* const c : myMatrix.getCells()) {
469 // update path cost
470 for (std::vector<RORoute*>::const_iterator j = c->pathsVector.begin(); j != c->pathsVector.end(); ++j) {
471 RORoute* r = *j;
473 }
474 // calculate route utilities and probabilities
475 RouteCostCalculator<RORoute, ROEdge, ROVehicle>::getCalculator().calculateProbabilities(c->pathsVector, myDefaultVehicle, 0);
476 // calculate route flows
477 for (std::vector<RORoute*>::const_iterator j = c->pathsVector.begin(); j != c->pathsVector.end(); ++j) {
478 RORoute* r = *j;
479 r->setProbability(r->getProbability() * c->vehicleNumber);
480 }
481 }
482 for (const auto& it : intervals) {
483 writeInterval(it.first, it.second);
484 }
485}
486
487
488double
489ROMAAssignments::getPenalizedEffort(const ROEdge* const e, const ROVehicle* const v, double t) {
490 const std::map<const ROEdge* const, double>::const_iterator i = myPenalties.find(e);
491 return i == myPenalties.end() ? e->getEffort(v, t) : e->getEffort(v, t) + i->second;
492}
493
494
495double
496ROMAAssignments::getPenalizedTT(const ROEdge* const e, const ROVehicle* const v, double t) {
497 const std::map<const ROEdge* const, double>::const_iterator i = myPenalties.find(e);
498 return i == myPenalties.end() ? e->getTravelTime(v, t) : e->getTravelTime(v, t) + i->second;
499}
500
501
502double
503ROMAAssignments::getTravelTime(const ROEdge* const e, const ROVehicle* const v, double t) {
504 return e->getTravelTime(v, t);
505}
506
507
508#ifdef HAVE_FOX
509// ---------------------------------------------------------------------------
510// ROMAAssignments::RoutingTask-methods
511// ---------------------------------------------------------------------------
512void
513ROMAAssignments::RoutingTask::run(MFXWorkerThread* context) {
514 myAssign.computePath(myCell, myBegin, myLinkFlow, &static_cast<RONet::WorkerThread*>(context)->getVehicleRouter(SVC_IGNORING), mySetBulkMode);
515}
516#endif
long long int SUMOTime
Definition GUI.h:36
#define WRITE_MESSAGE(msg)
Definition MsgHandler.h:288
#define TLF(string,...)
Definition MsgHandler.h:306
std::vector< const ROEdge * > ConstROEdgeVector
Definition ROEdge.h:57
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition SUMOTime.cpp:91
#define STEPS2TIME(x)
Definition SUMOTime.h:55
const std::string DEFAULT_VTYPE_ID
@ SVC_IGNORING
vehicles ignoring classes
std::vector< SUMOVehicleParameter::Stop > StopParVector
@ 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:80
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
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:73
bool hasLoadedTravelTime(double time) const
Returns whether a travel time for this edge was loaded.
Definition ROEdge.cpp:208
int getNumLanes() const
Returns the number of lanes this edge has.
Definition ROEdge.h:251
int getPriority() const
get edge priority (road class)
Definition ROEdge.h:533
bool isTazConnector() const
Definition ROEdge.h:174
double getSpeedLimit() const
Returns the speed allowed on this edge.
Definition ROEdge.h:240
static void disableTimelineWarning()
Definition ROEdge.h:520
SumoXMLEdgeFunc getFunction() const
Returns the function of the edge.
Definition ROEdge.h:209
double getTravelTime(const ROVehicle *const veh, double time) const
Returns the travel time for this edge.
Definition ROEdge.cpp:214
void addTravelTime(double value, double timeBegin, double timeEnd)
Adds a travel time value.
Definition ROEdge.cpp:171
double getEffort(const ROVehicle *const veh, double time) const
Returns the effort for this edge.
Definition ROEdge.cpp:178
double getLength() const
Returns the length of the edge.
Definition ROEdge.h:225
static const ROEdgeVector & getAllEdges()
Returns all ROEdges.
Definition ROEdge.cpp:375
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:63
SUMOVTypeParameter * getVehicleTypeSecure(const std::string &id)
Retrieves the named vehicle type.
Definition RONet.cpp:410
ROEdge * getEdge(const std::string &name) const
Retrieves an edge from the network.
Definition RONet.h:179
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:114
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.
#define UNUSED_PARAMETER(x)
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