Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/assign/duaIterateMix.py
169673 views
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
4
# Copyright (C) 2008-2025 German Aerospace Center (DLR) and others.
5
# This program and the accompanying materials are made available under the
6
# terms of the Eclipse Public License 2.0 which is available at
7
# https://www.eclipse.org/legal/epl-2.0/
8
# This Source Code may also be made available under the following Secondary
9
# Licenses when the conditions for such availability set forth in the Eclipse
10
# Public License 2.0 are satisfied: GNU General Public License, version 2
11
# or later which is available at
12
# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
13
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
14
15
# @file duaIterateMix.py
16
# @author Behzad Bamdad Mehrabani
17
# @author Jakob Erdmann
18
# @date 2022-08-10
19
20
"""
21
Run duarouter and sumo alternating to perform a mixed traffic assignment of user equilibrium and system optimum
22
(Mixed traffic flow of Human Driven Vehicles (HDVs) and Connected and Autonomous Vehicle (CAVs)).
23
It is assumed that HDVs follow user equilibrium and CAVs follow system optimum.
24
"""
25
from __future__ import print_function
26
from __future__ import absolute_import
27
28
import os
29
import sys
30
import subprocess
31
import glob
32
import argparse
33
import xml.etree.ElementTree as ET
34
35
36
from datetime import datetime
37
from costMemory import CostMemory
38
from duaIterate import addGenericOptions
39
from duaIterate import call
40
from duaIterate import get_scale
41
from duaIterate import get_dumpfilename
42
from duaIterate import get_weightfilename
43
from duaIterate import writeSUMOConf
44
from duaIterate import filterTripinfo
45
from duaIterate import assign_remaining_args
46
from duaIterate import get_basename
47
from duaIterate import calcMarginalCost
48
sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
49
50
import sumolib # noqa
51
from sumolib.options import ArgumentParser # noqa
52
53
DEBUGLOG = None
54
EDGEDATA_ADD = "edgedata.add.xml"
55
56
57
def initOptions():
58
argParser = ArgumentParser(
59
description=""" Any options of the form sumo--long-option-name will be passed to sumo.
60
These must be given after all the other options
61
example: sumo--step-length 0.5 will add the option --step-length 0.5 to sumo.""",
62
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
63
addGenericOptions(argParser)
64
65
argParser.add_argument("--continue-on-unbuild", action="store_true", dest="continueOnUnbuild",
66
default=False, help="continues on unbuild routes")
67
argParser.add_argument("-t", "--trips", type=ArgumentParser.route_file,
68
help="trips in step 0 (either trips, flows, or routes have to be supplied)", metavar="FILE")
69
argParser.add_argument("-r", "--routes", type=ArgumentParser.route_file,
70
help="routes in step 0 (either trips, flows, or routes have to be supplied)", metavar="FILE")
71
argParser.add_argument("-F", "--flows", type=ArgumentParser.route_file,
72
help="flows in step 0 (either trips, flows, or routes have to be supplied)", metavar="FILE")
73
argParser.add_argument("-A", "--gA",
74
type=float, default=.5, help="Sets Gawron's Alpha")
75
argParser.add_argument("-B", "--gBeta",
76
type=float, default=.9, help="Sets Gawron's Beta")
77
argParser.add_argument("-E", "--disable-summary", "--disable-emissions", action="store_true", dest="noSummary",
78
default=False, help="No summaries are written by the simulation")
79
argParser.add_argument("-T", "--disable-tripinfos", action="store_true", dest="noTripinfo",
80
default=False, help="No tripinfos are written by the simulation")
81
argParser.add_argument("--tripinfo-filter", dest="tripinfoFilter", type=str,
82
help="filter tripinfo attributes")
83
argParser.add_argument("--inc-start", dest="incStart",
84
type=float, default=0, help="Start for incrementing scale")
85
argParser.add_argument("--inc-max", dest="incMax",
86
type=float, default=1, help="Maximum for incrementing scale")
87
argParser.add_argument("--inc-base", dest="incBase", type=int, default=-1,
88
help="Give the incrementation base. Negative values disable incremental scaling")
89
argParser.add_argument("--incrementation", dest="incValue",
90
type=int, default=1, help="Give the incrementation")
91
argParser.add_argument("--time-inc", dest="timeInc",
92
type=int, default=0, help="Give the time incrementation")
93
argParser.add_argument("-f", "--first-step", dest="firstStep",
94
type=int, default=0, help="First DUA step")
95
argParser.add_argument("-l", "--last-step", dest="lastStep",
96
type=int, default=50, help="Last DUA step")
97
argParser.add_argument("--convergence-iterations", dest="convIt",
98
type=int, default=10, help="Number of iterations to use for convergence calculation")
99
argParser.add_argument("--max-convergence-deviation", dest="convDev",
100
type=float, help="Maximum relative standard deviation in travel times")
101
argParser.add_argument("-D", "--districts", help="use districts as sources and targets",
102
type=ArgumentParser.file, metavar="FILE")
103
argParser.add_argument("-x", "--vehroute-file", dest="routefile", type=str,
104
choices=['None', 'routesonly', 'detailed'],
105
default='None', help="choose the format of the route file")
106
argParser.add_argument("-z", "--output-lastRoute", action="store_true", dest="lastroute",
107
default=False, help="output the last routes")
108
argParser.add_argument("-K", "--keep-allroutes", action="store_true", dest="allroutes",
109
default=False, help="save routes with near zero probability")
110
argParser.add_argument("--routing-algorithm", default="dijkstra", type=str, help="select the routing algorithm")
111
argParser.add_argument("--max-alternatives-HDV", default=5, type=int, dest="max_alternatives_HDV",
112
help="prune the number of alternatives to INT for HDV")
113
argParser.add_argument("--max-alternatives-CAV", default=5, type=int, dest="max_alternatives_CAV",
114
help="prune the number of alternatives to INT for CAV")
115
argParser.add_argument("--skip-first-routing", action="store_true", dest="skipFirstRouting",
116
default=False, help="run simulation with demands before first routing")
117
argParser.add_argument("--logit", action="store_true", default=False, help="use the logit model for route choice")
118
argParser.add_argument("-g", "--logitbeta", type=float,
119
default=0.15, help="use the c-logit model for route choice; logit model when beta = 0")
120
argParser.add_argument("-i", "--logitgamma", type=float, default=1., help="use the c-logit model for route choice")
121
argParser.add_argument("-G", "--logittheta", type=float, help="parameter to adapt the cost unit")
122
argParser.add_argument("-J", "--addweights", type=str, help="Additional weights for duarouter")
123
argParser.add_argument("--convergence-steps", dest="convergenceSteps", type=int,
124
help="Given x, if x > 0 reduce probability to change route by 1/x per step "
125
"(Probabilistic Swapping (PSwap)). "
126
"If x < 0 set probability of rerouting to 1/step after step |x|")
127
argParser.add_argument("--addweights.once", dest="addweightsOnce", action="store_true",
128
default=False, help="use added weights only on the first iteration")
129
argParser.add_argument("--router-verbose", action="store_true",
130
default=False, help="let duarouter print some statistics")
131
argParser.add_argument("--weight-memory", action="store_true", default=False, dest="weightmemory",
132
help="smooth edge weights across iterations")
133
argParser.add_argument("--pessimism", default=1, type=float,
134
help="give traffic jams a higher weight when using option --weight-memory")
135
argParser.add_argument("--clean-alt", action="store_true", dest="clean_alt",
136
default=False, help="Whether old rou.alt.xml files shall be removed")
137
argParser.add_argument("--binary", dest="gzip", action="store_true", default=False,
138
help="alias for --gzip")
139
argParser.add_argument("--gzip", action="store_true", default=False,
140
help="writing intermediate and resulting route files in gzipped format")
141
argParser.add_argument("--dualog", default="dua.log", type=ArgumentParser.file,
142
help="log file path (default 'dua.log')")
143
argParser.add_argument("--log", default="stdout.log", type=ArgumentParser.file,
144
help="stdout log file path (default 'stdout.log')")
145
argParser.add_argument("--marginal-cost", action="store_true", default=False,
146
help="use marginal cost to perform system optimal traffic assignment")
147
argParser.add_argument("--marginal-cost-reverse", action="store_true", default=False,
148
help="use with mix option for reversing the marginal cost with original travel times")
149
argParser.add_argument("--mix", action="store_true", default=False, help="performing mix traffic assignment")
150
argParser.add_argument("--marginal-cost.exp", type=float, default=0, dest="mcExp",
151
help="apply the given exponent on the current traffic count when computing marginal cost")
152
argParser.add_argument("remaining_args", nargs='*')
153
return argParser
154
155
156
def writeRouteConfHDV(duarouterBinary, step, options, dua_args, file,
157
output, routesInfo):
158
filename = os.path.basename(file)
159
filename = filename.split('.')[0]
160
cfgname = "%03i/iteration_%03i_%s.duarcfg" % (step, step, filename)
161
args = [
162
'--net-file', options.net,
163
'--route-files', file,
164
'--output-file', output,
165
'--exit-times', str(routesInfo == "detailed"),
166
'--ignore-errors', str(options.continueOnUnbuild),
167
'--with-taz', str(options.districts is not None),
168
'--gawron.beta', str(options.gBeta),
169
'--gawron.a', str(options.gA),
170
'--keep-all-routes', str(options.allroutes),
171
'--routing-algorithm', options.routing_algorithm,
172
'--max-alternatives', str(options.max_alternatives_HDV),
173
'--weights.expand',
174
'--logit.beta', str(options.logitbeta),
175
'--logit.gamma', str(options.logitgamma),
176
'--random', str(options.absrand),
177
'--begin', str(options.begin),
178
'--verbose', str(options.router_verbose),
179
'--no-step-log',
180
'--no-warnings', str(options.noWarnings),
181
]
182
if options.districts:
183
args += ['--additional-files', options.districts]
184
if options.logit:
185
args += ['--route-choice-method', 'logit']
186
if options.MSA:
187
probKeepRoute = step/(step+1)
188
args += ['--keep-route-probability', str(probKeepRoute)]
189
if options.convergenceSteps:
190
if options.convergenceSteps > 0:
191
probKeepRoute = max(0, min(step / float(options.convergenceSteps), 1))
192
else:
193
startStep = -options.convergenceSteps
194
probKeepRoute = 0 if step > startStep else 1 - 1.0 / (step - startStep)
195
args += ['--keep-route-probability', str(probKeepRoute)]
196
197
if step > 0 or options.addweights:
198
weightpath = ""
199
if step > 0:
200
weightpath = get_weightfilename(options, step - 1, "dump")
201
if options.addweights and (step == 0 or not options.addweightsOnce):
202
if step > 0:
203
weightpath += ","
204
weightpath += options.addweights
205
args += ['--weight-files', weightpath]
206
if options.eco_measure:
207
args += ['--weight-attribute', options.eco_measure]
208
if 'CH' in options.routing_algorithm:
209
args += ['--weight-period', str(options.aggregation)]
210
if options.logittheta:
211
args += ['--logit.theta', str(options.logittheta)]
212
if options.end:
213
args += ['--end', str(options.end)]
214
215
args += ["--save-configuration", cfgname]
216
217
subprocess.call([duarouterBinary] + args + dua_args)
218
return cfgname
219
220
221
def writeRouteConfCAV(duarouterBinary, step, options, dua_args, file,
222
output, routesInfo):
223
filename = os.path.basename(file)
224
filename = filename.split('.')[0]
225
cfgname = "%03i/iteration_%03i_%s.duarcfg" % (step, step, filename)
226
args = [
227
'--net-file', options.net,
228
'--route-files', file,
229
'--output-file', output,
230
'--exit-times', str(routesInfo == "detailed"),
231
'--ignore-errors', str(options.continueOnUnbuild),
232
'--with-taz', str(options.districts is not None),
233
'--gawron.beta', str(options.gBeta),
234
'--gawron.a', str(options.gA),
235
'--keep-all-routes', str(options.allroutes),
236
'--routing-algorithm', options.routing_algorithm,
237
'--max-alternatives', str(options.max_alternatives_CAV),
238
'--weights.expand',
239
'--logit.beta', str(options.logitbeta),
240
'--logit.gamma', str(options.logitgamma),
241
'--random', str(options.absrand),
242
'--begin', str(options.begin),
243
'--verbose', str(options.router_verbose),
244
'--no-step-log',
245
'--no-warnings', str(options.noWarnings),
246
]
247
if options.districts:
248
args += ['--additional-files', options.districts]
249
if options.logit:
250
args += ['--route-choice-method', 'logit']
251
if options.MSA:
252
probKeepRoute = step/(step+1)
253
args += ['--keep-route-probability', str(probKeepRoute)]
254
if options.convergenceSteps:
255
if options.convergenceSteps > 0:
256
probKeepRoute = max(0, min(step / float(options.convergenceSteps), 1))
257
else:
258
startStep = -options.convergenceSteps
259
probKeepRoute = 0 if step > startStep else 1 - 1.0 / (step - startStep)
260
args += ['--keep-route-probability', str(probKeepRoute)]
261
262
if step > 0 or options.addweights:
263
weightpath = ""
264
if step > 0:
265
weightpath = get_weightfilename(options, step - 1, "dump")
266
if options.addweights and (step == 0 or not options.addweightsOnce):
267
if step > 0:
268
weightpath += ","
269
weightpath += options.addweights
270
args += ['--weight-files', weightpath]
271
if options.eco_measure:
272
args += ['--weight-attribute', options.eco_measure]
273
if 'CH' in options.routing_algorithm:
274
args += ['--weight-period', str(options.aggregation)]
275
if options.logittheta:
276
args += ['--logit.theta', str(options.logittheta)]
277
if options.end:
278
args += ['--end', str(options.end)]
279
280
args += ["--save-configuration", cfgname]
281
282
subprocess.call([duarouterBinary] + args + dua_args)
283
return cfgname
284
285
286
def calcMarginalCostReverse(step, options):
287
if step > 1:
288
if DEBUGLOG:
289
log = open("marginal_cost2.log", "w" if step == 2 else "a")
290
tree_sumo_cur = ET.parse(get_weightfilename(options, step - 1, "dump"))
291
tree_sumo_prv = ET.parse(get_weightfilename(options, step - 2, "dump"))
292
for interval_cur in tree_sumo_cur.getroot():
293
begin_cur = interval_cur.attrib.get("begin")
294
for interval_prv in tree_sumo_prv.getroot():
295
begin_prv = interval_prv.attrib.get("begin")
296
for edge_cur in interval_cur.iter('edge'):
297
for edge_prv in interval_prv.iter('edge'):
298
if begin_cur == begin_prv and edge_cur.get("id") == edge_prv.get("id"):
299
if edge_cur.get("traveltime") is not None and edge_prv.get(
300
"traveltime") is not None:
301
tt_cur = float(edge_cur.get("overlapTraveltime"))
302
edge_cur.set("traveltime", str(tt_cur))
303
tree_sumo_cur.write(get_weightfilename(options, step - 1, "dump"))
304
305
if DEBUGLOG:
306
log.close()
307
308
309
def calcMixTrips(step, options):
310
input_demands = options.trips.split(",")
311
input_demands_1 = options.routes.split(",")
312
routesSuffix = ".xml"
313
trips_CAV = ["%03i/%s_%03i.rou%s" % (step, get_basename(f), step, routesSuffix)
314
for f in input_demands_1]
315
trips_HDV = ["%03i/%s_%03i.rou%s" % (step, get_basename(f), step, routesSuffix)
316
for f in input_demands]
317
src_tree = ET.parse(str(trips_CAV[0]))
318
dest_tree = ET.parse(str(trips_HDV[0]))
319
src_root = src_tree.getroot()
320
dest_root = dest_tree.getroot()
321
322
# temporary remove vtypes
323
vType1 = dest_root.find("vType")
324
dest_root.remove(vType1)
325
vType2 = src_root.find("vType")
326
src_root.remove(vType2)
327
328
for n in range(10000000):
329
src_tag = src_root.find('./vehicle')
330
if src_tag is None:
331
break
332
dest_root.append(src_tag)
333
src_root.remove(src_tag)
334
335
dest_root[:] = sorted(dest_root, key=lambda child: (child.tag, float(child.get("depart"))))
336
for n in range(10000000):
337
dest_tag_2 = dest_root.find('./vehicle')
338
if dest_tag_2 is None:
339
break
340
src_root.append(dest_tag_2)
341
dest_root.remove(dest_tag_2)
342
343
# Put the 'vType' element on HDV file
344
src_root.insert(0, vType1)
345
src_root.insert(1, vType2)
346
ET.ElementTree(src_root).write(os.path.join((str(trips_HDV[0]))))
347
# if DEBUGLOG:
348
# log.close()
349
350
351
def main(args=None):
352
argParser = initOptions()
353
354
try:
355
options = argParser.parse_args(args=args)
356
except (NotImplementedError, ValueError) as e:
357
print(e, file=sys.stderr)
358
sys.exit(1)
359
360
if not options.net:
361
argParser.error("Option --net-file is mandatory")
362
if (not options.trips and not options.routes and not options.flows):
363
argParser.error(
364
"Either --trips, --flows, or --routes have to be given!")
365
duaBinary = sumolib.checkBinary("duarouter", options.path)
366
sumoBinary = sumolib.checkBinary("sumo", options.path)
367
if options.addweights and options.weightmemory:
368
argParser.error("Options --addweights and --weight-memory are mutually exclusive.")
369
if options.marginal_cost and not options.logit:
370
print("Warning! --marginal-cost works best with --logit.", file=sys.stderr)
371
372
# make sure BOTH binaries are callable before we start
373
try:
374
subprocess.call(duaBinary, stdout=subprocess.PIPE)
375
except OSError:
376
sys.exit(
377
("Error: Could not locate duarouter (%s).\nMake sure its on the search path or set environment " +
378
"variable DUAROUTER_BINARY\n") % duaBinary)
379
try:
380
subprocess.call(sumoBinary, stdout=subprocess.PIPE)
381
except OSError:
382
sys.exit(
383
("Error: Could not locate sumo (%s).\nMake sure its on the search path or set environment " +
384
"variable SUMO_BINARY\n") % sumoBinary)
385
386
sumo_args = assign_remaining_args(sumoBinary, 'sumo', options.remaining_args)
387
dua_args = assign_remaining_args(duaBinary, 'duarouter', options.remaining_args)
388
sys.stdout = sumolib.TeeFile(sys.stdout, open(options.log, "w+"))
389
log = open(options.dualog, "w+")
390
if options.zip:
391
if options.clean_alt:
392
sys.exit("Error: Please use either --zip or --clean-alt but not both.")
393
try:
394
subprocess.call("7z", stdout=open(os.devnull, 'wb'))
395
except Exception:
396
sys.exit("Error: Could not locate 7z, please make sure its on the search path.")
397
zipProcesses = {}
398
zipLog = open("7zip.log", "w+")
399
starttime = datetime.now()
400
if options.trips:
401
input_demands = options.trips.split(",")
402
if options.routes:
403
input_demands_1 = options.routes.split(",")
404
if options.trips and not options.routes:
405
print("Please insert HDVs trip by -t and CAVs trips by -r")
406
if options.routes and not options.trips:
407
print("Please insert HDVs trip by -t and CAVs trips by -r")
408
if options.weightmemory:
409
costmemory = CostMemory('traveltime', pessimism=options.pessimism, network_file=options.net
410
)
411
routesSuffix = ".xml"
412
if options.gzip:
413
routesSuffix = ".gz"
414
415
if options.weightmemory and options.firstStep != 0:
416
# load previous dump files when continuing a run
417
print(">> Reassembling cost-memory from previous iteration steps")
418
for step in range(0, options.firstStep):
419
dumpfile = get_dumpfilename(options, step, "dump")
420
print(">>> Loading %s" % dumpfile)
421
costmemory.load_costs(dumpfile, step, get_scale(options, step))
422
423
# write detectorfile
424
with open(EDGEDATA_ADD, 'w') as fd:
425
vTypes = ' vTypes="%s"' % ' '.join(options.measureVTypes.split(',')) if options.measureVTypes else ""
426
print("<a>", file=fd)
427
print(' <edgeData id="dump_%s" freq="%s" file="%s" excludeEmpty="true" minSamples="1"%s/>' % (
428
options.aggregation,
429
options.aggregation,
430
get_dumpfilename(options, -1, "dump", False),
431
vTypes), file=fd)
432
if options.eco_measure:
433
print((' <edgeData id="eco_%s" type="hbefa" freq="%s" file="%s" ' +
434
'excludeEmpty="true" minSamples="1"%s/>') % (
435
options.aggregation,
436
options.aggregation,
437
get_dumpfilename(options, step, "dump", False),
438
vTypes), file=fd)
439
print("</a>", file=fd)
440
441
avgTT = sumolib.miscutils.Statistics()
442
for step in range(options.firstStep, options.lastStep):
443
current_directory = os.getcwd()
444
final_directory = os.path.join(current_directory, "%03i" % step)
445
if not os.path.exists(final_directory):
446
os.makedirs(final_directory)
447
btimeA = datetime.now()
448
print("> Executing step %s" % step)
449
# working on CAVs demand
450
router_demands = input_demands
451
simulation_demands = input_demands
452
# demand files have regular names based on the basename and the step
453
if not (options.skipFirstRouting and step == 0):
454
simulation_demands = ["%03i/%s_%03i.rou%s" % (step, get_basename(f), step, routesSuffix)
455
for f in input_demands]
456
if not ((options.skipFirstRouting and step == 1) or step == 0):
457
router_demands = ["%03i/%s_%03i.rou.alt%s" % (step-1, get_basename(f), step-1, routesSuffix)
458
for f in input_demands]
459
460
if not (options.skipFirstRouting and step == options.firstStep):
461
# call duarouter
462
for router_input, output in zip(router_demands, simulation_demands):
463
print(">> Running router on %s" % router_input)
464
btime = datetime.now()
465
print(">>> Begin time: %s" % btime)
466
cfgname = writeRouteConfHDV(duaBinary, step, options, dua_args, router_input,
467
output, options.routefile)
468
log.flush()
469
sys.stdout.flush()
470
if options.marginal_cost_reverse:
471
calcMarginalCostReverse(step, options)
472
call([duaBinary, "-c", cfgname], log)
473
if options.clean_alt and router_input not in input_demands:
474
os.remove(router_input)
475
etime = datetime.now()
476
print(">>> End time: %s" % etime)
477
print(">>> Duration: %s" % (etime - btime))
478
print("<<")
479
# working on HDVs demand
480
router_demands = input_demands_1
481
simulation_demands = input_demands_1
482
# demand files have regular names based on the basename and the step
483
if not (options.skipFirstRouting and step == 0):
484
simulation_demands = ["%03i/%s_%03i.rou%s" % (step, get_basename(f), step, routesSuffix)
485
for f in input_demands_1]
486
if not ((options.skipFirstRouting and step == 1) or step == 0):
487
router_demands = ["%03i/%s_%03i.rou.alt%s" % (step-1, get_basename(f), step-1, routesSuffix)
488
for f in input_demands_1]
489
490
if not (options.skipFirstRouting and step == options.firstStep):
491
# call duarouter
492
for router_input, output in zip(router_demands, simulation_demands):
493
print(">> Running router on %s" % router_input)
494
btime = datetime.now()
495
print(">>> Begin time: %s" % btime)
496
cfgname = writeRouteConfCAV(duaBinary, step, options, dua_args, router_input,
497
output, options.routefile)
498
log.flush()
499
sys.stdout.flush()
500
if options.marginal_cost:
501
calcMarginalCost(step, options)
502
503
call([duaBinary, "-c", cfgname], log)
504
if options.clean_alt and router_input not in input_demands_1:
505
os.remove(router_input)
506
etime = datetime.now()
507
print(">>> End time: %s" % etime)
508
print(">>> Duration: %s" % (etime - btime))
509
print("<<")
510
# combining trips file
511
if options.mix:
512
calcMixTrips(step, options)
513
# simulation
514
simulation_demands = ["%03i/%s_%03i.rou%s" % (step, get_basename(f), step, routesSuffix)
515
for f in input_demands]
516
print(">> Running simulation")
517
btime = datetime.now()
518
print(">>> Begin time: %s" % btime)
519
sumocfg = writeSUMOConf(sumoBinary, step, options, sumo_args,
520
",".join(simulation_demands)) # todo: change 'grou.xml'
521
log.flush()
522
sys.stdout.flush()
523
call([sumoBinary, "-c", sumocfg], log)
524
if options.tripinfoFilter:
525
filterTripinfo(step, options.tripinfoFilter.split(","))
526
etime = datetime.now()
527
print(">>> End time: %s" % etime)
528
print(">>> Duration: %s" % (etime - btime))
529
print("<<")
530
531
if options.weightmemory:
532
print(">> Smoothing edge weights")
533
costmemory.load_costs(get_dumpfilename(options, step, "dump"), step, get_scale(options, step))
534
costmemory.write_costs(get_weightfilename(options, step, "dump"))
535
print(">>> Updated %s edges" % costmemory.loaded())
536
print(">>> Decayed %s unseen edges" % costmemory.decayed())
537
print(">>> Error avg:%.12g mean:%.12g" % (costmemory.avg_error(), costmemory.mean_error()))
538
print(">>> Absolute Error avg:%.12g mean:%.12g" %
539
(costmemory.avg_abs_error(), costmemory.mean_abs_error()))
540
541
if options.zip and step - options.firstStep > 1:
542
# this is a little hackish since we zip and remove all files by glob, which may have undesired side effects
543
# also note that the 7z file does not have an "_" before the
544
# iteration number in order to be not picked up by the remove
545
for s in list(zipProcesses.keys()):
546
if zipProcesses[s].poll() is not None:
547
for f in glob.glob("*_%03i*" % s):
548
try:
549
os.remove(f)
550
except Exception:
551
print("Could not remove %s" % f, file=zipLog)
552
del zipProcesses[s]
553
zipStep = step - 2
554
zipProcesses[zipStep] = subprocess.Popen(
555
["7z", "a", "iteration%03i.7z" % zipStep, "%03i" % zipStep], stdout=zipLog,
556
stderr=zipLog)
557
558
converged = False
559
if options.convDev:
560
sum = 0.
561
count = 0
562
for t in sumolib.output.parse_fast("%03i/tripinfo_%03i.xml" % (step, step),
563
'tripinfo', ['duration']):
564
sum += float(t.duration)
565
count += 1
566
avgTT.add(sum / count)
567
relStdDev = avgTT.relStdDev(options.convIt)
568
print("< relative travel time deviation in the last %s steps: %.05f" % (
569
min(avgTT.count(), options.convIt), relStdDev))
570
if avgTT.count() >= options.convIt and relStdDev < options.convDev:
571
converged = True
572
573
print("< Step %s ended (duration: %s)" %
574
(step, datetime.now() - btimeA))
575
print("------------------\n")
576
577
log.flush()
578
sys.stdout.flush()
579
if converged:
580
break
581
if options.zip:
582
for s in zipProcesses.keys():
583
zipProcesses[s].wait()
584
for f in glob.glob("*_%03i*" % s):
585
try:
586
os.remove(f)
587
except Exception:
588
print("Could not remove %s" % f, file=zipLog)
589
zipLog.close()
590
print("dua-iterate ended (duration: %s)" % (datetime.now() - starttime))
591
592
log.close()
593
sys.stdout.close()
594
sys.stdout = sys.__stdout__
595
596
597
if __name__ == "__main__":
598
main()
599
600