Note
Go to the end to download the full example code
Forecasting#
In this example, we present a full forecasting workflow for the Sioux Falls example model.
Imports
from uuid import uuid4
from tempfile import gettempdir
from os.path import join
from aequilibrae.utils.create_example import create_example
import logging
import sys
We create the example project inside our temp folder
fldr = join(gettempdir(), uuid4().hex)
project = create_example(fldr)
logger = project.logger
# We get the project open, and we can tell the logger to direct all messages to the terminal as well
stdout_handler = logging.StreamHandler(sys.stdout)
formatter = logging.Formatter("%(asctime)s;%(levelname)s ; %(message)s")
stdout_handler.setFormatter(formatter)
logger.addHandler(stdout_handler)
Traffic assignment with skimming#
from aequilibrae.paths import TrafficAssignment, TrafficClass
We build all graphs
project.network.build_graphs()
# We get warnings that several fields in the project are filled with NaNs.
# This is true, but we won't use those fields
2023-12-16 11:44:40,994;WARNING ; Field(s) name, lanes has(ve) at least one NaN value. Check your computations
2023-12-16 11:44:41,021;WARNING ; Field(s) name, lanes has(ve) at least one NaN value. Check your computations
2023-12-16 11:44:41,049;WARNING ; Field(s) name, lanes has(ve) at least one NaN value. Check your computations
2023-12-16 11:44:41,076;WARNING ; Field(s) name, lanes has(ve) at least one NaN value. Check your computations
2023-12-16 11:44:41,103;WARNING ; Field(s) name, lanes has(ve) at least one NaN value. Check your computations
2023-12-16 11:44:41,130;WARNING ; Field(s) name, lanes has(ve) at least one NaN value. Check your computations
We grab the graph for cars
graph = project.network.graphs["c"]
# Let's say we want to minimize the free_flow_time
graph.set_graph("free_flow_time")
# And will skim time and distance while we are at it
graph.set_skimming(["free_flow_time", "distance"])
# And we will allow paths to be computed going through other centroids/centroid connectors
# required for the Sioux Falls network, as all nodes are centroids
graph.set_blocked_centroid_flows(False)
2023-12-16 11:44:41,148;WARNING ; Cost field with wrong type. Converting to float64
We get the demand matrix directly from the project record So let’s inspect what we have in the project
proj_matrices = project.matrices
print(proj_matrices.list())
name file_name ... description status
0 demand_omx demand.omx ... Original data imported to OMX format
1 demand_mc demand_mc.omx ... None
2 skims skims.omx ... Example skim
3 demand_aem demand.aem ... Original data imported to AEM format
[4 rows x 8 columns]
Let’s get it in this better way
demand = proj_matrices.get_matrix("demand_omx")
demand.computational_view(["matrix"])
assig = TrafficAssignment()
# Create the assignment class
assigclass = TrafficClass(name="car", graph=graph, matrix=demand)
# The first thing to do is to add at list of traffic classes to be assigned
assig.add_class(assigclass)
# We set these parameters only after adding one class to the assignment
assig.set_vdf("BPR") # This is not case-sensitive
# Then we set the volume delay function
assig.set_vdf_parameters({"alpha": "b", "beta": "power"}) # And its parameters
assig.set_capacity_field("capacity") # The capacity and free flow travel times as they exist in the graph
assig.set_time_field("free_flow_time")
# And the algorithm we want to use to assign
assig.set_algorithm("bfw")
# Since I haven't checked the parameters file, let's make sure convergence criteria is good
assig.max_iter = 1000
assig.rgap_target = 0.001
assig.execute() # we then execute the assignment
2023-12-16 11:44:41,426;INFO ; Traffic Class specification
2023-12-16 11:44:41,426;INFO ; {'car': {'Graph': "{'Mode': 'c', 'Block through centroids': False, 'Number of centroids': 24, 'Links': 76, 'Nodes': 24}", 'Matrix': "{'Source': '/tmp/11a7c6bb4dbc4d48ba04119c02aa5133/matrices/demand.omx', 'Number of centroids': 24, 'Matrix cores': ['matrix'], 'Matrix totals': {'matrix': 360600.0}}"}}
2023-12-16 11:44:41,426;INFO ; Traffic Assignment specification
2023-12-16 11:44:41,426;INFO ; {'VDF parameters': {'alpha': 'b', 'beta': 'power'}, 'VDF function': 'bpr', 'Number of cores': 4, 'Capacity field': 'capacity', 'Time field': 'free_flow_time', 'Algorithm': 'bfw', 'Maximum iterations': 250, 'Target RGAP': 0.0001}
2023-12-16 11:44:41,428;WARNING ; Cost field with wrong type. Converting to float64
2023-12-16 11:44:41,428;INFO ; bfw Assignment STATS
2023-12-16 11:44:41,428;INFO ; Iteration, RelativeGap, stepsize
2023-12-16 11:44:41,433;INFO ; 1,inf,1.0
2023-12-16 11:44:41,441;INFO ; 2,0.8550751349428284,0.32839952448634563
2023-12-16 11:44:41,445;INFO ; 3,0.4763455007221067,0.18660240547488702
2023-12-16 11:44:41,450;INFO ; 4,0.2355126365951965,0.2411477440291793
2023-12-16 11:44:41,454;INFO ; 5,0.10924072010481088,0.8185470737942447
2023-12-16 11:44:41,459;INFO ; 6,0.1980945227617506,0.14054330572978305
2023-12-16 11:44:41,469;INFO ; 7,0.0668172221544687,0.36171152718899247
2023-12-16 11:44:41,473;INFO ; 8,0.06792122267870587,0.9634685345644044
2023-12-16 11:44:41,478;INFO ; 9,0.10705582933092855,0.13757153109677187
2023-12-16 11:44:41,484;INFO ; 10,0.04038814432034622,0.16094034254279727
2023-12-16 11:44:41,488;INFO ; 11,0.02580122618377297,0.7164350576171253
2023-12-16 11:44:41,498;INFO ; 12,0.04284643717317079,0.08581544277016757
2023-12-16 11:44:41,503;INFO ; 13,0.01697166233340693,0.16601579690331672
2023-12-16 11:44:41,509;INFO ; 14,0.020396548012131713,0.4461322062863033
2023-12-16 11:44:41,514;INFO ; 15,0.025887901335904493,0.08515995223661305
2023-12-16 11:44:41,521;INFO ; 16,0.015188959427662916,0.19886983426700164
2023-12-16 11:44:41,525;INFO ; 17,0.014751419643228847,0.35488561597157137
2023-12-16 11:44:41,530;INFO ; 18,0.015582407302127564,0.061454151540815266
2023-12-16 11:44:41,537;INFO ; 19,0.008935871473338545,0.08603462968532587
2023-12-16 11:44:41,541;INFO ; 20,0.008477045208211687,0.1668913886047941
2023-12-16 11:44:41,546;INFO ; 21,0.00951758140998847,0.49170991560106375
2023-12-16 11:44:41,552;INFO ; 22,0.013060711845092096,0.060284308755226904
2023-12-16 11:44:41,561;INFO ; 23,0.006861821876765184,0.10954009782378028
2023-12-16 11:44:41,568;INFO ; 24,0.006201113315688106,0.12230718464288659
2023-12-16 11:44:41,573;INFO ; 25,0.007457404973803635,0.3080614235512333
2023-12-16 11:44:41,577;INFO ; 26,0.006900497787038874,0.32835666337215824
2023-12-16 11:44:41,582;INFO ; 27,0.00696355413239051,0.7377893941134753
2023-12-16 11:44:41,587;INFO ; 28,0.006817764279833669,0.044387076869910204
2023-12-16 11:44:41,592;INFO ; 29,0.004277860366532803,0.054318136217836
2023-12-16 11:44:41,600;INFO ; 30,0.0041361810963813075,0.05758294976347517
2023-12-16 11:44:41,604;INFO ; 31,0.0031483923250301984,0.0918038853550413
2023-12-16 11:44:41,613;INFO ; 32,0.0034184967969887975,0.12279944254981216
2023-12-16 11:44:41,620;INFO ; 33,0.002738614050254446,0.08799214942490213
2023-12-16 11:44:41,624;INFO ; 34,0.0023403784016334354,0.10982599850072697
2023-12-16 11:44:41,629;INFO ; 35,0.002318543550206424,0.18741920884722726
2023-12-16 11:44:41,633;INFO ; 36,0.0023838181828798113,0.14049673625040277
2023-12-16 11:44:41,640;INFO ; 37,0.0017801377860527383,0.25278698153091705
2023-12-16 11:44:41,649;INFO ; 38,0.0019264349761434177,0.30768123024794486
2023-12-16 11:44:41,667;INFO ; 39,0.0018408894375067505,0.3982324050251883
2023-12-16 11:44:41,673;INFO ; 40,0.0018205742523363442,0.5255149131178805
2023-12-16 11:44:41,678;INFO ; 41,0.002022417110832812,0.012343794696314879
2023-12-16 11:44:41,682;INFO ; 42,0.0014238367784734874,0.030454026217362696
2023-12-16 11:44:41,687;INFO ; 43,0.0011877471305869146,0.022833087486082083
2023-12-16 11:44:41,692;INFO ; 44,0.0012106681494600422,0.06969126002892642
2023-12-16 11:44:41,696;INFO ; 45,0.0011336232568071574,0.03897096468599959
2023-12-16 11:44:41,701;INFO ; 46,0.00097809890526807,0.02207199085154752
2023-12-16 11:44:41,701;INFO ; bfw Assignment finished. 46 iterations and 0.00097809890526807 final gap
Convergence report is easy to see
import pandas as pd
convergence_report = assig.report()
print(convergence_report.head())
iteration rgap alpha warnings beta0 beta1 beta2
0 1 inf 1.000000 1.000000 0.000000 0.0
1 2 0.855075 0.328400 1.000000 0.000000 0.0
2 3 0.476346 0.186602 1.000000 0.000000 0.0
3 4 0.235513 0.241148 1.000000 0.000000 0.0
4 5 0.109241 0.818547 0.607382 0.392618 0.0
volumes = assig.results()
print(volumes.head())
matrix_ab matrix_ba matrix_tot ... PCE_AB PCE_BA PCE_tot
link_id ...
1 4565.043510 NaN 4565.043510 ... 4565.043510 NaN 4565.043510
2 8152.210795 NaN 8152.210795 ... 8152.210795 NaN 8152.210795
3 4552.603997 NaN 4552.603997 ... 4552.603997 NaN 4552.603997
4 5988.789717 NaN 5988.789717 ... 5988.789717 NaN 5988.789717
5 8164.650309 NaN 8164.650309 ... 8164.650309 NaN 8164.650309
[5 rows x 15 columns]
We could export it to CSV or AequilibraE data, but let’s put it directly into the results database
assig.save_results("base_year_assignment")
And save the skims
assig.save_skims("base_year_assignment_skims", which_ones="all", format="omx")
2023-12-16 11:44:41,757;WARNING ; Matrix Record has been saved to the database
Trip distribution#
Calibration#
We will calibrate synthetic gravity models using the skims for TIME that we just generated
import numpy as np
from aequilibrae.distribution import GravityCalibration
Let’s take another look at what we have in terms of matrices in the model
print(proj_matrices.list())
name ... status
0 demand_omx ...
1 demand_mc ...
2 skims ...
3 demand_aem ...
4 base_year_assignment_skims_car ...
[5 rows x 8 columns]
We need the demand
demand = proj_matrices.get_matrix("demand_aem")
# And the skims
imped = proj_matrices.get_matrix("base_year_assignment_skims_car")
We can check which matrix cores were created for our skims to decide which one to use
imped.names
# Where ``free_flow_time_final`` is actually the congested time for the last iteration
['distance_blended', 'distance_final', 'free_flow_time_blended', 'free_flow_time_final']
But before using the data, let’s get some impedance for the intrazonals Let’s assume it is 75% of the closest zone
imped_core = "free_flow_time_final"
imped.computational_view([imped_core])
# If we run the code below more than once, we will be overwriting the diagonal values with non-sensical data
# so let's zero it first
np.fill_diagonal(imped.matrix_view, 0)
# We compute it with a little bit of NumPy magic
intrazonals = np.amin(imped.matrix_view, where=imped.matrix_view > 0, initial=imped.matrix_view.max(), axis=1)
intrazonals *= 0.75
# Then we fill in the impedance matrix
np.fill_diagonal(imped.matrix_view, intrazonals)
Since we are working with an OMX file, we cannot overwrite a matrix on disk So we give a new name to save it
imped.save(names=["final_time_with_intrazonals"])
This also updates these new matrices as those being used for computation As one can verify below
imped.view_names
['final_time_with_intrazonals']
We set the matrices for being used in computation
demand.computational_view(["matrix"])
for function in ["power", "expo"]:
gc = GravityCalibration(matrix=demand, impedance=imped, function=function, nan_as_zero=True)
gc.calibrate()
model = gc.model
# We save the model
model.save(join(fldr, f"{function}_model.mod"))
# We can save the result of applying the model as well
# We can also save the calibration report
with open(join(fldr, f"{function}_convergence.log"), "w") as otp:
for r in gc.report:
otp.write(r + "\n")
Forecast#
We create a set of ‘future’ vectors using some random growth factors. We apply the model for inverse power, as the trip frequency length distribution (TFLD) seems to be a better fit for the actual one.
from aequilibrae.distribution import Ipf, GravityApplication, SyntheticGravityModel
from aequilibrae.matrix import AequilibraeData
We compute the vectors from our matrix
origins = np.sum(demand.matrix_view, axis=1)
destinations = np.sum(demand.matrix_view, axis=0)
args = {
"file_path": join(fldr, "synthetic_future_vector.aed"),
"entries": demand.zones,
"field_names": ["origins", "destinations"],
"data_types": [np.float64, np.float64],
"memory_mode": False,
}
vectors = AequilibraeData()
vectors.create_empty(**args)
vectors.index[:] = demand.index[:]
# Then grow them with some random growth between 0 and 10%, and balance them
vectors.origins[:] = origins * (1 + np.random.rand(vectors.entries) / 10)
vectors.destinations[:] = destinations * (1 + np.random.rand(vectors.entries) / 10)
vectors.destinations *= vectors.origins.sum() / vectors.destinations.sum()
Impedance#
imped = proj_matrices.get_matrix("base_year_assignment_skims_car")
imped.computational_view(["final_time_with_intrazonals"])
# If we wanted the main diagonal to not be considered...
# ``np.fill_diagonal(imped.matrix_view, np.nan)``
for function in ["power", "expo"]:
model = SyntheticGravityModel()
model.load(join(fldr, f"{function}_model.mod"))
outmatrix = join(proj_matrices.fldr, f"demand_{function}_model.aem")
args = {
"impedance": imped,
"rows": vectors,
"row_field": "origins",
"model": model,
"columns": vectors,
"column_field": "destinations",
"nan_as_zero": True,
}
gravity = GravityApplication(**args)
gravity.apply()
# We get the output matrix and save it to OMX too,
gravity.save_to_project(name=f"demand_{function}_modeled", file_name=f"demand_{function}_modeled.omx")
2023-12-16 11:44:42,430;WARNING ; Matrix Record has been saved to the database
2023-12-16 11:44:42,523;WARNING ; Matrix Record has been saved to the database
We update the matrices table/records and verify that the new matrices are indeed there
proj_matrices.update_database()
print(proj_matrices.list())
name ... status
0 demand_omx ...
1 demand_mc ...
2 skims ...
3 demand_aem ...
4 base_year_assignment_skims_car ...
5 demand_power_modeled ...
6 demand_expo_modeled ...
[7 rows x 8 columns]
IPF for the future vectors#
args = {
"matrix": demand,
"rows": vectors,
"columns": vectors,
"column_field": "destinations",
"row_field": "origins",
"nan_as_zero": True,
}
ipf = Ipf(**args)
ipf.fit()
ipf.save_to_project(name="demand_ipfd", file_name="demand_ipfd.aem")
ipf.save_to_project(name="demand_ipfd_omx", file_name="demand_ipfd.omx")
2023-12-16 11:44:42,596;WARNING ; Matrix Record has been saved to the database
2023-12-16 11:44:42,616;WARNING ; Matrix Record has been saved to the database
<aequilibrae.project.data.matrix_record.MatrixRecord object at 0x7f422f8636a0>
df = proj_matrices.list()
Future traffic assignment#
from aequilibrae.paths import TrafficAssignment, TrafficClass
logger.info("\n\n\n TRAFFIC ASSIGNMENT FOR FUTURE YEAR")
2023-12-16 11:44:42,634;INFO ;
TRAFFIC ASSIGNMENT FOR FUTURE YEAR
demand = proj_matrices.get_matrix("demand_ipfd")
# Let's see what is the core we ended up getting. It should be 'gravity'
demand.names
['matrix']
Let’s use the IPF matrix
demand.computational_view("matrix")
assig = TrafficAssignment()
# Creates the assignment class
assigclass = TrafficClass(name="car", graph=graph, matrix=demand)
# The first thing to do is to add at a list of traffic classes to be assigned
assig.add_class(assigclass)
assig.set_vdf("BPR") # This is not case-sensitive
# Then we set the volume delay function
assig.set_vdf_parameters({"alpha": "b", "beta": "power"}) # And its parameters
assig.set_capacity_field("capacity") # The capacity and free flow travel times as they exist in the graph
assig.set_time_field("free_flow_time")
# And the algorithm we want to use to assign
assig.set_algorithm("bfw")
# Since I haven't checked the parameters file, let's make sure convergence criteria is good
assig.max_iter = 500
assig.rgap_target = 0.00001
OPTIONAL
# If we want to execute select link analysis on a particular TrafficClass, we set the links we are analyzing.
# The format of the input select links is a dictionary (str: list[tuple]).
# Each entry represents a separate set of selected links to compute. The str name will name the set of links.
# The list[tuple] is the list of links being selected, of the form (link_id, direction), as it occurs in the Graph.
# Direction can be 0, 1, -1. 0 denotes bi-directionality
# For example, let's use Select Link on two sets of links:
select_links = {
"Leaving node 1": [(1, 1), (2, 1)],
"Random nodes": [(3, 1), (5, 1)],
}
# We call this command on the class we are analyzing with our dictionary of values
assigclass.set_select_links(select_links)
assig.execute() # we then execute the assignment
/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/aequilibrae/paths/traffic_class.py:166: UserWarning: Input string name has a space in it. Replacing with _
warnings.warn("Input string name has a space in it. Replacing with _")
2023-12-16 11:44:42,904;INFO ; Traffic Class specification
2023-12-16 11:44:42,905;INFO ; {'car': {'Graph': "{'Mode': 'c', 'Block through centroids': False, 'Number of centroids': 24, 'Links': 76, 'Nodes': 24}", 'Matrix': "{'Source': '/tmp/11a7c6bb4dbc4d48ba04119c02aa5133/matrices/demand_ipfd.aem', 'Number of centroids': 24, 'Matrix cores': ['matrix'], 'Matrix totals': {'matrix': 380209.9560367887}}", 'select_links': "{'Leaving node 1': [(1, 1), (2, 1)], 'Random nodes': [(3, 1), (5, 1)]}"}}
2023-12-16 11:44:42,905;INFO ; Traffic Assignment specification
2023-12-16 11:44:42,905;INFO ; {'VDF parameters': {'alpha': 'b', 'beta': 'power'}, 'VDF function': 'bpr', 'Number of cores': 4, 'Capacity field': 'capacity', 'Time field': 'free_flow_time', 'Algorithm': 'bfw', 'Maximum iterations': 250, 'Target RGAP': 0.0001}
2023-12-16 11:44:42,907;WARNING ; Cost field with wrong type. Converting to float64
2023-12-16 11:44:42,907;INFO ; bfw Assignment STATS
2023-12-16 11:44:42,907;INFO ; Iteration, RelativeGap, stepsize
2023-12-16 11:44:42,916;INFO ; 1,inf,1.0
2023-12-16 11:44:42,922;INFO ; 2,0.8801167770779192,0.3255768552847432
2023-12-16 11:44:42,929;INFO ; 3,0.5240770672592922,0.17309184829410232
2023-12-16 11:44:42,937;INFO ; 4,0.30032538574191375,0.1603642573166719
2023-12-16 11:44:42,942;INFO ; 5,0.1352370179046365,0.49701179927679373
2023-12-16 11:44:42,949;INFO ; 6,0.20794420068930453,0.15241277229822453
2023-12-16 11:44:42,954;INFO ; 7,0.09831636179950806,0.3808347251551354
2023-12-16 11:44:42,961;INFO ; 8,0.10900630857033705,0.14650684041497886
2023-12-16 11:44:42,969;INFO ; 9,0.045258241390832205,0.6652265027085433
2023-12-16 11:44:42,974;INFO ; 10,0.1677335653155051,0.09887812023873423
2023-12-16 11:44:42,985;INFO ; 11,0.04816844856101315,0.10116362884971669
2023-12-16 11:44:42,990;INFO ; 12,0.031029206456437117,0.37095873406075286
2023-12-16 11:44:42,997;INFO ; 13,0.06271029098866976,0.09209653055870863
2023-12-16 11:44:43,002;INFO ; 14,0.02927187887225578,0.1478087316425489
2023-12-16 11:44:43,007;INFO ; 15,0.026421703976390504,0.6189490901145938
2023-12-16 11:44:43,013;INFO ; 16,0.0491295384308294,0.0816081574359833
2023-12-16 11:44:43,025;INFO ; 17,0.023577084557279204,0.1538349305689063
2023-12-16 11:44:43,033;INFO ; 18,0.01871592412474153,0.1850641151136487
2023-12-16 11:44:43,041;INFO ; 19,0.01681526653382726,0.8266166505532883
2023-12-16 11:44:43,046;INFO ; 20,0.035950674001634986,0.04968462323436491
2023-12-16 11:44:43,052;INFO ; 21,0.013361841019926426,0.054028585650882206
2023-12-16 11:44:43,058;INFO ; 22,0.008488814546920555,0.08427264159198235
2023-12-16 11:44:43,064;INFO ; 23,0.00850027589962604,0.13253199305725283
2023-12-16 11:44:43,073;INFO ; 24,0.008570533872879503,0.22141693091729853
2023-12-16 11:44:43,078;INFO ; 25,0.010044116854261867,0.49165251193117315
2023-12-16 11:44:43,084;INFO ; 26,0.011781973480816787,0.038087537355086215
2023-12-16 11:44:43,089;INFO ; 27,0.006363449556324485,0.08979339343129421
2023-12-16 11:44:43,097;INFO ; 28,0.008578871387693518,0.12317342330741385
2023-12-16 11:44:43,102;INFO ; 29,0.006700356700564501,0.09234482925022913
2023-12-16 11:44:43,109;INFO ; 30,0.005281955947905048,0.037439173636325145
2023-12-16 11:44:43,114;INFO ; 31,0.0037567056047787904,0.14994718481184244
2023-12-16 11:44:43,119;INFO ; 32,0.004790399117129396,0.2892099233034445
2023-12-16 11:44:43,124;INFO ; 33,0.005643083059314969,0.5921174662954949
2023-12-16 11:44:43,130;INFO ; 34,0.006101637557603018,0.04289320346632887
2023-12-16 11:44:43,137;INFO ; 35,0.0039052208598397316,0.035161341052874
2023-12-16 11:44:43,142;INFO ; 36,0.002603384818534169,0.020854068432046957
2023-12-16 11:44:43,147;INFO ; 37,0.0018107209306306175,0.033710075734057876
2023-12-16 11:44:43,153;INFO ; 38,0.0029348014719752036,0.05425651116088603
2023-12-16 11:44:43,158;INFO ; 39,0.002455622424715581,0.08316135026987756
2023-12-16 11:44:43,163;INFO ; 40,0.0026544431328034994,0.061502773005646626
2023-12-16 11:44:43,168;INFO ; 41,0.0020304763301888474,0.06601594809193209
2023-12-16 11:44:43,174;INFO ; 42,0.0021142607022135826,0.08362686563139646
2023-12-16 11:44:43,179;INFO ; 43,0.0018465563068604167,0.05242847408615088
2023-12-16 11:44:43,184;INFO ; 44,0.0018153653153141797,0.13688598311194003
2023-12-16 11:44:43,189;INFO ; 45,0.0018838425802846061,0.0859736216248934
2023-12-16 11:44:43,194;INFO ; 46,0.001738826060065422,0.06107213344422784
2023-12-16 11:44:43,199;INFO ; 47,0.0014587729013779687,0.11146144473213283
2023-12-16 11:44:43,205;INFO ; 48,0.0014809197814975457,0.10604486755096845
2023-12-16 11:44:43,213;INFO ; 49,0.0018306453682204278,0.20251336275184667
2023-12-16 11:44:43,225;INFO ; 50,0.0026853278264933078,0.3180670895546641
2023-12-16 11:44:43,233;INFO ; 51,0.0022459867526378593,0.6531461109177804
2023-12-16 11:44:43,241;INFO ; 52,0.002195805220093396,0.02177728290919995
2023-12-16 11:44:43,246;INFO ; 53,0.0015450864048416326,0.014525657027073459
2023-12-16 11:44:43,258;INFO ; 54,0.0012228917123035428,0.014770788961724759
2023-12-16 11:44:43,265;INFO ; 55,0.0010586613209191704,0.02269918494118205
2023-12-16 11:44:43,273;INFO ; 56,0.001050900510766628,0.023729935650219577
2023-12-16 11:44:43,281;INFO ; 57,0.0008526154646601244,0.02248636426877017
2023-12-16 11:44:43,289;INFO ; 58,0.0008897416056941696,0.015542585234481142
2023-12-16 11:44:43,297;INFO ; 59,0.0006195321752505868,0.01656577816661174
2023-12-16 11:44:43,302;INFO ; 60,0.0006053467174987775,0.02481756124623766
2023-12-16 11:44:43,309;INFO ; 61,0.0006284657697377061,0.023706594419342992
2023-12-16 11:44:43,314;INFO ; 62,0.0005637427650831432,0.035609736347236895
2023-12-16 11:44:43,321;INFO ; 63,0.0006482866217228363,0.04195863282417273
2023-12-16 11:44:43,326;INFO ; 64,0.0005556755440941251,0.042972125704256896
2023-12-16 11:44:43,333;INFO ; 65,0.0005077586172684462,0.022882894593847052
2023-12-16 11:44:43,338;INFO ; 66,0.0005163423621542958,0.09278489938562719
2023-12-16 11:44:43,345;INFO ; 67,0.0006390430292594777,0.10526071955162761
2023-12-16 11:44:43,350;INFO ; 68,0.0006445329311539463,0.1294513485317989
2023-12-16 11:44:43,357;INFO ; 69,0.0005858191457974622,0.12289920961503457
2023-12-16 11:44:43,365;INFO ; 70,0.0006207344301877027,0.2651984583421351
2023-12-16 11:44:43,373;INFO ; 71,0.0006722357746465636,0.39691437015618625
2023-12-16 11:44:43,378;INFO ; 72,0.00078330711012096,0.42805690236282984
2023-12-16 11:44:43,383;INFO ; 73,0.0007470642674322552,0.5151974208141227
2023-12-16 11:44:43,393;INFO ; 74,0.0007298505767710091,0.008844393528335198
2023-12-16 11:44:43,401;INFO ; 75,0.0007667557278239385,0.011319630516197578
2023-12-16 11:44:43,409;INFO ; 76,0.0007505908767094384,0.007171306983000899
2023-12-16 11:44:43,417;INFO ; 77,0.0004748842999712344,0.011536211152511099
2023-12-16 11:44:43,424;INFO ; 78,0.0005182151941193632,0.008574665660182227
2023-12-16 11:44:43,433;INFO ; 79,0.0003842729194578263,0.0071167872643832794
2023-12-16 11:44:43,438;INFO ; 80,0.00031297736223891994,0.01071859219015401
2023-12-16 11:44:43,443;INFO ; 81,0.0004509342683112314,0.014556359059526314
2023-12-16 11:44:43,448;INFO ; 82,0.00041826190713459586,0.028735908373010433
2023-12-16 11:44:43,453;INFO ; 83,0.00036731065937415904,0.014006096971559877
2023-12-16 11:44:43,461;INFO ; 84,0.00034383254340520416,0.01209015333912584
2023-12-16 11:44:43,469;INFO ; 85,0.00033556166650366184,0.015413536951896026
2023-12-16 11:44:43,474;INFO ; 86,0.00026552677960087895,0.008364083339778026
2023-12-16 11:44:43,479;INFO ; 87,0.00020089796346633835,0.0035427724141319887
2023-12-16 11:44:43,484;INFO ; 88,0.00021944972912952884,0.007395901178123471
2023-12-16 11:44:43,489;INFO ; 89,0.00014612550742091094,0.005109871143727618
2023-12-16 11:44:43,494;INFO ; 90,0.00017608592414201075,0.011036357091271137
2023-12-16 11:44:43,500;INFO ; 91,0.00016913778503675,0.006663564016823964
2023-12-16 11:44:43,505;INFO ; 92,0.0001250370876586504,0.007090220201867676
2023-12-16 11:44:43,517;INFO ; 93,9.958120131002119e-05,0.004008255942568072
2023-12-16 11:44:43,523;INFO ; 94,0.00012273469318727087,0.004715736567444669
2023-12-16 11:44:43,528;INFO ; 95,9.837794837161969e-05,0.005793617022941344
2023-12-16 11:44:43,533;INFO ; 96,9.552428964810578e-05,0.003971205406151417
2023-12-16 11:44:43,538;INFO ; 97,8.818540531818559e-05,0.006339768841252695
2023-12-16 11:44:43,543;INFO ; 98,9.333780823632336e-05,0.0047744465210120815
2023-12-16 11:44:43,549;INFO ; 99,7.32547147206754e-05,0.003604232987941905
2023-12-16 11:44:43,561;INFO ; 100,5.905456829910547e-05,0.006427000218226626
2023-12-16 11:44:43,569;INFO ; 101,0.00010048408702023976,0.0077642890957961164
2023-12-16 11:44:43,574;INFO ; 102,8.130941922255969e-05,0.006586631653990435
2023-12-16 11:44:43,579;INFO ; 103,0.00012487308226516474,0.012350741604009879
2023-12-16 11:44:43,585;INFO ; 104,0.00010969773134322458,0.014798451368639887
2023-12-16 11:44:43,590;INFO ; 105,0.00012361977062953227,0.013298403122673374
2023-12-16 11:44:43,600;INFO ; 106,0.00011920081116651307,0.013319227955306469
2023-12-16 11:44:43,606;INFO ; 107,0.00012278716664713561,0.020699618368266226
2023-12-16 11:44:43,613;INFO ; 108,0.0001499961224810946,0.020250677663826305
2023-12-16 11:44:43,621;INFO ; 109,0.00017042343061078198,0.029257475360561495
2023-12-16 11:44:43,626;INFO ; 110,0.00018603047390417017,0.03233389779004673
2023-12-16 11:44:43,631;INFO ; 111,0.00016722221327262658,0.054054590498395894
2023-12-16 11:44:43,637;INFO ; 112,0.0002399904515217466,0.06914640039241467
2023-12-16 11:44:43,645;INFO ; 113,0.00025384328816214266,0.07459013714048128
2023-12-16 11:44:43,653;INFO ; 114,0.00023115673119499964,0.12475219209729697
2023-12-16 11:44:43,661;INFO ; 115,0.00021144851997362176,0.052160836896337395
2023-12-16 11:44:43,666;INFO ; 116,0.00018483728940885686,0.11467417888212338
2023-12-16 11:44:43,673;INFO ; 117,0.00027162146637460554,0.11071485152658067
2023-12-16 11:44:43,678;INFO ; 118,0.00018384917945483793,0.09032999953393618
2023-12-16 11:44:43,688;INFO ; 119,0.00023272307125016926,0.11353838084665968
2023-12-16 11:44:43,693;INFO ; 120,0.00020994058480430731,0.21988673737387304
2023-12-16 11:44:43,701;INFO ; 121,0.00034047492011564075,0.19168951429983977
2023-12-16 11:44:43,706;INFO ; 122,0.0002653085254602558,0.4492294041229853
2023-12-16 11:44:43,713;INFO ; 123,0.00021055273088249564,0.4203114057719075
2023-12-16 11:44:43,718;INFO ; 124,0.00021227871210736558,0.6986651889185885
2023-12-16 11:44:43,724;INFO ; 125,0.00021637960127048018,0.002463733032266089
2023-12-16 11:44:43,732;INFO ; 126,0.00017079324771004727,0.0018277290606938585
2023-12-16 11:44:43,740;INFO ; 127,0.00014045754884917913,0.0018848246559973214
2023-12-16 11:44:43,748;INFO ; 128,0.00018054985025685606,0.005269621247749041
2023-12-16 11:44:43,757;INFO ; 129,0.00018592342324233327,0.006818360740330572
2023-12-16 11:44:43,762;INFO ; 130,0.00015255025649706178,0.007866680953558325
2023-12-16 11:44:43,769;INFO ; 131,0.00010966883939053544,0.0019410366587447375
2023-12-16 11:44:43,775;INFO ; 132,7.232255455599916e-05,0.003050801140102955
2023-12-16 11:44:43,780;INFO ; 133,9.820596444532282e-05,0.003834188854327017
2023-12-16 11:44:43,785;INFO ; 134,8.150883343069787e-05,0.004083438791825662
2023-12-16 11:44:43,791;INFO ; 135,7.44319789882611e-05,0.0015926217692614666
2023-12-16 11:44:43,796;INFO ; 136,7.574955313697436e-05,0.0025966986883294184
2023-12-16 11:44:43,809;INFO ; 137,9.578056843693463e-05,0.00356478715848148
2023-12-16 11:44:43,822;INFO ; 138,7.76360737505028e-05,0.0036175576321579713
2023-12-16 11:44:43,829;INFO ; 139,8.106438591481385e-05,0.0027043748520239707
2023-12-16 11:44:43,834;INFO ; 140,6.780633988870577e-05,0.0033819292358257366
2023-12-16 11:44:43,839;INFO ; 141,7.304200548377631e-05,0.00425858519341537
2023-12-16 11:44:43,844;INFO ; 142,5.736645560945985e-05,0.003002174485139541
2023-12-16 11:44:43,850;INFO ; 143,6.0190242063129826e-05,0.007956628981977984
2023-12-16 11:44:43,857;INFO ; 144,0.0001155264748775691,0.011356802890695286
2023-12-16 11:44:43,862;INFO ; 145,0.00010485921982749527,0.010179943286936133
2023-12-16 11:44:43,868;INFO ; 146,6.592271956752245e-05,0.004645686478866028
2023-12-16 11:44:43,877;INFO ; 147,4.5748966197147094e-05,0.0026211784054317035
2023-12-16 11:44:43,882;INFO ; 148,4.3187317922486255e-05,0.002064053059839029
2023-12-16 11:44:43,889;INFO ; 149,3.272826938908335e-05,0.0012151742790269652
2023-12-16 11:44:43,897;INFO ; 150,2.9245461121818584e-05,0.0005490695245251501
2023-12-16 11:44:43,902;INFO ; 151,2.0982844621358165e-05,0.0002615466937860982
2023-12-16 11:44:43,907;INFO ; 152,1.9590818732864647e-05,0.000483478114444336
2023-12-16 11:44:43,912;INFO ; 153,2.3852216013317623e-05,0.0007595282012005339
2023-12-16 11:44:43,917;INFO ; 154,2.3726572881746672e-05,0.0005073719533955558
2023-12-16 11:44:43,922;INFO ; 155,2.4995212105769126e-05,0.001295326828542139
2023-12-16 11:44:43,927;INFO ; 156,2.0342701850114074e-05,0.0011808681953322851
2023-12-16 11:44:43,936;INFO ; 157,2.0024806414081226e-05,0.0011867131958859711
2023-12-16 11:44:43,941;INFO ; 158,1.9151993974621344e-05,0.001519156913378732
2023-12-16 11:44:43,947;INFO ; 159,1.5877752485755626e-05,0.0006513542451566182
2023-12-16 11:44:43,953;INFO ; 160,1.2918793768609883e-05,0.0006901790865932784
2023-12-16 11:44:43,961;INFO ; 161,1.2467398482706138e-05,0.0004144972099122386
2023-12-16 11:44:43,966;INFO ; 162,1.0946568812584058e-05,0.0007353737700889362
2023-12-16 11:44:43,971;INFO ; 163,9.778384313365728e-06,0.0004240588314504945
2023-12-16 11:44:43,971;INFO ; bfw Assignment finished. 163 iterations and 9.778384313365728e-06 final gap
Now let us save our select link results, all we need to do is provide it with a name In addition to exporting the select link flows, it also exports the Select Link matrices in OMX format.
assig.save_select_link_results("select_link_analysis")
Say we just want to save our select link flows, we can call:
assig.save_select_link_flows("just_flows")
# Or if we just want the SL matrices:
assig.save_select_link_matrices("just_matrices")
# Internally, the save_select_link_results calls both of these methods at once.
# We could export it to CSV or AequilibraE data, but let's put it directly into the results database
assig.save_results("future_year_assignment")
# And save the skims
assig.save_skims("future_year_assignment_skims", which_ones="all", format="omx")
2023-12-16 11:44:44,036;WARNING ; Matrix Record has been saved to the database
We can also plot convergence#
import matplotlib.pyplot as plt
df = assig.report()
x = df.iteration.values
y = df.rgap.values
fig = plt.figure()
ax = fig.add_subplot(111)
plt.plot(x, y, "k--")
plt.yscale("log")
plt.grid(True, which="both")
plt.xlabel(r"Iterations")
plt.ylabel(r"Relative Gap")
plt.show()

Close the project
project.close()
Total running time of the script: (0 minutes 3.516 seconds)