7.10. Forecasting

On 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
from aequilibrae import logger
import logging
import sys

We create the example project inside our temp folder

fldr = join(gettempdir(), uuid4().hex)

project = create_example(fldr)

# We the project open, 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;%(name)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.  Which is true, but we won't use those fields

Out:

2021-01-14 09:21:11,582;aequilibrae;WARNING ; Fields were removed from Graph for being non-numeric: modes,link_type
2021-01-14 09:21:11,584;aequilibrae;WARNING ; Field(s) name,lanes has(ve) at least one NaN value. Check your computations
2021-01-14 09:21:11,585;aequilibrae;WARNING ; Field(s) name,lanes has(ve) at least one NaN value. Check your computations
2021-01-14 09:21:11,587;aequilibrae;WARNING ; Field(s) name,lanes has(ve) at least one NaN value. Check your computations
2021-01-14 09:21:11,588;aequilibrae;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 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 compute going through other centroids/centroid connectors
# required for the Sioux Falls network, as all nodes are centroids
graph.set_blocked_centroid_flows(False)
# We get the demand matrix directly from the project record
# so let's inspect what we have in the project
proj_matrices = project.matrices
proj_matrices.list()
name file_name cores procedure procedure_id timestamp description status
0 demand_aem demand.aem 1 None None 2020-11-24 08:46:42 Original data imported to AEM format\n
1 demand_omx demand.omx 1 None None 2020-11-24 08:47:18 Original data imported to OMX format
2 skims skims.omx 2 None None Example skim


# Let's get it in this better way
demand = proj_matrices.get_matrix('demand_omx')
demand.computational_view(['matrix'])
assig = TrafficAssignment()

# Creates the assignment class
assigclass = TrafficClass(graph, 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

Out:

2021-01-14 09:21:11,997;aequilibrae;INFO ; bfw Assignment STATS
2021-01-14 09:21:11,997;aequilibrae;INFO ; Iteration, RelativeGap, stepsize
2021-01-14 09:21:12,100;aequilibrae;INFO ; 1,inf,1.0
2021-01-14 09:21:12,204;aequilibrae;INFO ; 2,0.8485503509703024,0.36497345609427145
2021-01-14 09:21:12,307;aequilibrae;INFO ; 3,0.3813926225800203,0.2298356924660528
2021-01-14 09:21:12,412;aequilibrae;INFO ; 4,0.19621277462606984,0.18591312145268074
2021-01-14 09:21:12,519;aequilibrae;INFO ; 5,0.09069073200924213,0.7090816523174254
2021-01-14 09:21:12,623;aequilibrae;INFO ; 6,0.20600048221061426,0.1229016022154401
2021-01-14 09:21:12,729;aequilibrae;INFO ; 7,0.06710568925282254,0.38638656717489844
2021-01-14 09:21:12,836;aequilibrae;INFO ; 8,0.10307514154369488,0.1093055036410267
2021-01-14 09:21:12,942;aequilibrae;INFO ; 9,0.04222147191362779,0.2487805192125393
2021-01-14 09:21:13,046;aequilibrae;INFO ; 10,0.05926435464772421,0.15904810628271004
2021-01-14 09:21:13,149;aequilibrae;INFO ; 11,0.03453951151333739,0.5180973804491722
2021-01-14 09:21:13,256;aequilibrae;INFO ; 12,0.059426517206032654,0.10197123112986584
2021-01-14 09:21:13,360;aequilibrae;INFO ; 13,0.023239895792359067,0.1780595483940025
2021-01-14 09:21:13,463;aequilibrae;INFO ; 14,0.017873783562205998,0.9787872930853664
2021-01-14 09:21:13,570;aequilibrae;INFO ; 15,0.049661371545771556,0.08320656307451389
2021-01-14 09:21:13,674;aequilibrae;INFO ; 16,0.021382882276233087,0.11517403065013918
2021-01-14 09:21:13,778;aequilibrae;INFO ; 17,0.013141542820482906,0.10640369388111594
2021-01-14 09:21:13,883;aequilibrae;INFO ; 18,0.009902228209039313,0.10710395766777006
2021-01-14 09:21:13,987;aequilibrae;INFO ; 19,0.008834657139075773,0.2524678977926848
2021-01-14 09:21:14,092;aequilibrae;INFO ; 20,0.01037104162273405,0.672783938935575
2021-01-14 09:21:14,198;aequilibrae;INFO ; 21,0.011090096306112919,0.07468060074370476
2021-01-14 09:21:14,303;aequilibrae;INFO ; 22,0.006512685266481729,0.12485017624661685
2021-01-14 09:21:14,409;aequilibrae;INFO ; 23,0.005238884615251675,0.06316016574610187
2021-01-14 09:21:14,513;aequilibrae;INFO ; 24,0.003949529236289854,0.09717896243712648
2021-01-14 09:21:14,619;aequilibrae;INFO ; 25,0.003282221301580423,0.1577590171880403
2021-01-14 09:21:14,726;aequilibrae;INFO ; 26,0.0057928324528667054,0.45247656699511957
2021-01-14 09:21:14,830;aequilibrae;INFO ; 27,0.0066823585472082035,0.7851865570315525
2021-01-14 09:21:14,935;aequilibrae;INFO ; 28,0.005992619218871392,0.03909810047559774
2021-01-14 09:21:15,038;aequilibrae;INFO ; 29,0.0040313646880229485,0.04253018777364977
2021-01-14 09:21:15,143;aequilibrae;INFO ; 30,0.0027696521195955236,0.022512872266868305
2021-01-14 09:21:15,247;aequilibrae;INFO ; 31,0.0024846461521885483,0.045801692933285426
2021-01-14 09:21:15,350;aequilibrae;INFO ; 32,0.0016385526468732255,0.03429583308494769
2021-01-14 09:21:15,454;aequilibrae;INFO ; 33,0.0014956911143795503,0.03539200254746481
2021-01-14 09:21:15,558;aequilibrae;INFO ; 34,0.0011355392148568219,0.05358983822746
2021-01-14 09:21:15,661;aequilibrae;INFO ; 35,0.0012151973759507247,0.047571304687631016
2021-01-14 09:21:15,765;aequilibrae;INFO ; 36,0.001239365147988278,0.06536473861293134
2021-01-14 09:21:15,869;aequilibrae;INFO ; 37,0.0010684962819863329,0.10703952287434068
2021-01-14 09:21:15,977;aequilibrae;INFO ; 38,0.0010899690080088834,0.0986406240944672
2021-01-14 09:21:16,080;aequilibrae;INFO ; 39,0.0009886948497197317,0.06027623911565202
2021-01-14 09:21:16,186;aequilibrae;INFO ; 40,0.0012632086912186262,0.22288089471588354
2021-01-14 09:21:16,289;aequilibrae;INFO ; 41,0.001165571653411883,0.1977596494198537
2021-01-14 09:21:16,393;aequilibrae;INFO ; 42,0.0012299958308316802,0.3170348486824528
2021-01-14 09:21:16,497;aequilibrae;INFO ; 43,0.0012902531663786525,0.3422879827743953
2021-01-14 09:21:16,603;aequilibrae;INFO ; 44,0.0009979531087593776,0.7332060974425909
2021-01-14 09:21:16,603;aequilibrae;INFO ; bfw Assignment finished. 44 iterations and 0.0009979531087593776 final gap
# Convergence report is easy to see
import pandas as pd

convergence_report = assig.report()
convergence_report.head()
iteration rgap alpha warnings beta0 beta1 beta2
0 1 inf 1.000000 1.000000 0.000000 0.000000
1 2 0.848550 0.364973 1.000000 0.000000 0.000000
2 3 0.381393 0.229836 1.000000 0.000000 0.000000
3 4 0.196213 0.185913 0.959771 0.040229 0.000000
4 5 0.090691 0.709082 0.687640 0.286705 0.025654


volumes = assig.results()
volumes.head()
matrix_ab matrix_ba matrix_tot Congested_Time_AB Congested_Time_BA Congested_Time_Max Delay_factor_AB Delay_factor_BA Delay_factor_Max VOC_AB VOC_BA VOC_max PCE_AB PCE_BA PCE_tot
link_id
1 4570.421761 NaN 4570.421761 6.0 NaN 6.0 1.0 NaN 1.0 0.176463 NaN 0.176463 4570.421761 NaN 4570.421761
2 8275.382482 NaN 8275.382482 4.0 NaN 4.0 1.0 NaN 1.0 0.353596 NaN 0.353596 8275.382482 NaN 8275.382482
3 4675.373252 NaN 4675.373252 6.0 NaN 6.0 1.0 NaN 1.0 0.180515 NaN 0.180515 4675.373252 NaN 4675.373252
4 5900.513362 NaN 5900.513362 5.0 NaN 5.0 1.0 NaN 1.0 1.190056 NaN 1.190056 5900.513362 NaN 5900.513362
5 8170.430991 NaN 8170.430991 4.0 NaN 4.0 1.0 NaN 1.0 0.349112 NaN 0.349112 8170.430991 NaN 8170.430991


# 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')

Out:

2021-01-14 09:21:16,862;aequilibrae;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
proj_matrices.list()
name file_name cores procedure procedure_id timestamp description status
0 demand_aem demand.aem 1 None None 2020-11-24 08:46:42 Original data imported to AEM format\n
1 demand_omx demand.omx 1 None None 2020-11-24 08:47:18 Original data imported to OMX format
2 skims skims.omx 2 None None Example skim
3 base_year_assignment_skims base_year_assignment_skims.omx 4 Traffic Assignment 7096734d6fe94d5bbe5a610fd59e3953 2021-01-14 09:21:11.650854 Skimming for assignment procedure


# We need the demand
demand = proj_matrices.get_matrix('demand_aem')

# And the skims
imped = proj_matrices.get_matrix('base_year_assignment_skims')
# 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

Out:

['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

Out:

['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')

Out:

/home/runner/work/aequilibrae/aequilibrae/aequilibrae/distribution/gravity_application.py:316: RuntimeWarning: divide by zero encountered in power
  * a)[:]
/home/runner/work/aequilibrae/aequilibrae/aequilibrae/distribution/gravity_application.py:326: RuntimeWarning: invalid value encountered in multiply
  self.output.matrix_view[:, :] = self.output.matrix_view[:, :] * non_inf
## Forecast
#  * We create a set of * 'future' * vectors using some random growth factors
#  * We apply the model for inverse power, as the TFLD seems to be a better fit for the actual one
from aequilibrae.distribution import Ipf, GravityApplication, SyntheticGravityModel
from aequilibrae.matrix import AequilibraeData
import numpy as np
# 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% - Plus 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')
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')
    apply = GravityApplication()
    args = {"impedance": imped,
            "rows": vectors,
            "row_field": "origins",
            "model": model,
            "columns": vectors,
            "column_field": "destinations",
            "nan_as_zero": True
            }

    gravity = GravityApplication(**args)
    gravity.apply()

    gravity.save_to_project(name=f'demand_{function}_model', file_name=f'demand_{function}_model.aem')

    # We get the output matrix and save it to OMX too,
    gravity.save_to_project(name=f'demand_{function}_model_omx', file_name=f'demand_{function}_model.omx')

Out:

2021-01-14 09:21:17,989;aequilibrae;WARNING ; Matrix Record has been saved to the database
2021-01-14 09:21:18,161;aequilibrae;WARNING ; Matrix Record has been saved to the database
2021-01-14 09:21:18,477;aequilibrae;WARNING ; Matrix Record has been saved to the database
2021-01-14 09:21:18,649;aequilibrae;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()
proj_matrices.list()
name file_name cores procedure procedure_id timestamp description status
0 demand_aem demand.aem 1 None None 2020-11-24 08:46:42 Original data imported to AEM format\n
1 demand_omx demand.omx 1 None None 2020-11-24 08:47:18 Original data imported to OMX format
2 skims skims.omx 2 None None Example skim
3 base_year_assignment_skims base_year_assignment_skims.omx 4 Traffic Assignment 7096734d6fe94d5bbe5a610fd59e3953 2021-01-14 09:21:11.650854 Skimming for assignment procedure
4 demand_power_model demand_power_model.aem 1 Synthetic gravity trip distribution f326a431d88e4106bb804713ceb66f17 2021-01-14 09:21:17.831451 Synthetic gravity trip distribution. POWER
5 demand_power_model_omx demand_power_model.omx 1 Synthetic gravity trip distribution f326a431d88e4106bb804713ceb66f17 2021-01-14 09:21:17.831451 Synthetic gravity trip distribution. POWER
6 demand_expo_model demand_expo_model.aem 1 Synthetic gravity trip distribution 482ed7b45c90458b97276b1911e5cf35 2021-01-14 09:21:18.320908 Synthetic gravity trip distribution. EXPO
7 demand_expo_model_omx demand_expo_model.omx 1 Synthetic gravity trip distribution 482ed7b45c90458b97276b1911e5cf35 2021-01-14 09:21:18.320908 Synthetic gravity trip distribution. EXPO


### We now run 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_ipf', file_name='demand_ipf.aem')
ipf.save_to_project(name='demand_ipf_omx', file_name='demand_ipf.omx')

Out:

2021-01-14 09:21:18,863;aequilibrae;WARNING ; Matrix Record has been saved to the database
2021-01-14 09:21:19,033;aequilibrae;WARNING ; Matrix Record has been saved to the database

<aequilibrae.project.data.matrix_record.MatrixRecord object at 0x7f2c240fe350>
proj_matrices.list()
name file_name cores procedure procedure_id timestamp description status
0 demand_aem demand.aem 1 None None 2020-11-24 08:46:42 Original data imported to AEM format\n
1 demand_omx demand.omx 1 None None 2020-11-24 08:47:18 Original data imported to OMX format
2 skims skims.omx 2 None None Example skim
3 base_year_assignment_skims base_year_assignment_skims.omx 4 Traffic Assignment 7096734d6fe94d5bbe5a610fd59e3953 2021-01-14 09:21:11.650854 Skimming for assignment procedure
4 demand_power_model demand_power_model.aem 1 Synthetic gravity trip distribution f326a431d88e4106bb804713ceb66f17 2021-01-14 09:21:17.831451 Synthetic gravity trip distribution. POWER
5 demand_power_model_omx demand_power_model.omx 1 Synthetic gravity trip distribution f326a431d88e4106bb804713ceb66f17 2021-01-14 09:21:17.831451 Synthetic gravity trip distribution. POWER
6 demand_expo_model demand_expo_model.aem 1 Synthetic gravity trip distribution 482ed7b45c90458b97276b1911e5cf35 2021-01-14 09:21:18.320908 Synthetic gravity trip distribution. EXPO
7 demand_expo_model_omx demand_expo_model.omx 1 Synthetic gravity trip distribution 482ed7b45c90458b97276b1911e5cf35 2021-01-14 09:21:18.320908 Synthetic gravity trip distribution. EXPO
8 demand_ipf demand_ipf.aem 1 Iterative Proportional fitting fd6482afa209490cb48dc49dab1c4a50 2021-01-14 09:21:18.742840 None
9 demand_ipf_omx demand_ipf.omx 1 Iterative Proportional fitting fd6482afa209490cb48dc49dab1c4a50 2021-01-14 09:21:18.742840 None


## Future traffic assignment
from aequilibrae.paths import TrafficAssignment, TrafficClass
from aequilibrae import logger
import logging
logger.info('\n\n\n TRAFFIC ASSIGNMENT FOR FUTURE YEAR')

Out:

2021-01-14 09:21:19,099;aequilibrae;INFO ;


 TRAFFIC ASSIGNMENT FOR FUTURE YEAR
demand = proj_matrices.get_matrix('demand_power_model')

# let's see what is the core we ended up getting. It should be 'gravity'
demand.names

Out:

['gravity']
# Let's use the IPF matrix
demand.computational_view('gravity')

assig = TrafficAssignment()

# Creates the assignment class
assigclass = TrafficClass(graph, demand)

# The first thing to do is to add at 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 = 1000
assig.rgap_target = 0.0001

assig.execute()  # we then execute the assignment

Out:

2021-01-14 09:21:19,507;aequilibrae;INFO ; bfw Assignment STATS
2021-01-14 09:21:19,508;aequilibrae;INFO ; Iteration, RelativeGap, stepsize
2021-01-14 09:21:19,610;aequilibrae;INFO ; 1,inf,1.0
2021-01-14 09:21:19,713;aequilibrae;INFO ; 2,0.891252062704975,0.2950507455406328
2021-01-14 09:21:19,817;aequilibrae;INFO ; 3,0.6067577591653384,0.18474835602218154
2021-01-14 09:21:19,921;aequilibrae;INFO ; 4,0.32136254653004837,0.18523683318526393
2021-01-14 09:21:20,028;aequilibrae;INFO ; 5,0.15457332246299696,0.40825757881578517
2021-01-14 09:21:20,132;aequilibrae;INFO ; 6,0.20110207495887053,0.16179608227609468
2021-01-14 09:21:20,236;aequilibrae;INFO ; 7,0.11691060669798978,0.31282094569343716
2021-01-14 09:21:20,341;aequilibrae;INFO ; 8,0.12273568858193125,0.1560103828229713
2021-01-14 09:21:20,445;aequilibrae;INFO ; 9,0.08724541271025363,0.24555135531594735
2021-01-14 09:21:20,549;aequilibrae;INFO ; 10,0.08603412151722285,0.43665277065643143
2021-01-14 09:21:20,653;aequilibrae;INFO ; 11,0.11293875089777289,0.09189041652214892
2021-01-14 09:21:20,760;aequilibrae;INFO ; 12,0.05203389988408055,0.3083308313787385
2021-01-14 09:21:20,865;aequilibrae;INFO ; 13,0.07106115875002696,0.6745646818198204
2021-01-14 09:21:20,972;aequilibrae;INFO ; 14,0.0962098222082957,0.05824537289856114
2021-01-14 09:21:21,077;aequilibrae;INFO ; 15,0.04327428525787028,0.1219097255339215
2021-01-14 09:21:21,182;aequilibrae;INFO ; 16,0.03406762851563897,0.3491706947042233
2021-01-14 09:21:21,286;aequilibrae;INFO ; 17,0.041354298972319736,0.5054958595659316
2021-01-14 09:21:21,390;aequilibrae;INFO ; 18,0.033858531163256246,0.07979844323752343
2021-01-14 09:21:21,497;aequilibrae;INFO ; 19,0.027002914758835296,0.12180599394755749
2021-01-14 09:21:21,603;aequilibrae;INFO ; 20,0.025165695144201607,0.22746959010011605
2021-01-14 09:21:21,710;aequilibrae;INFO ; 21,0.022014199895245865,0.26717718731794643
2021-01-14 09:21:21,814;aequilibrae;INFO ; 22,0.01747237156848938,0.7965108414757822
2021-01-14 09:21:21,918;aequilibrae;INFO ; 23,0.026455483793932918,0.0640283943468921
2021-01-14 09:21:22,025;aequilibrae;INFO ; 24,0.017802030149778526,0.07912546520783795
2021-01-14 09:21:22,130;aequilibrae;INFO ; 25,0.012240381585188623,0.09543792353768395
2021-01-14 09:21:22,234;aequilibrae;INFO ; 26,0.01158256100026776,0.2007974572137156
2021-01-14 09:21:22,337;aequilibrae;INFO ; 27,0.01163888677512365,0.23891668421986748
2021-01-14 09:21:22,440;aequilibrae;INFO ; 28,0.01259469805559505,0.6798747230518891
2021-01-14 09:21:22,544;aequilibrae;INFO ; 29,0.01603597675003369,0.046215335263659216
2021-01-14 09:21:22,648;aequilibrae;INFO ; 30,0.00908215192379975,0.0495197337340773
2021-01-14 09:21:22,752;aequilibrae;INFO ; 31,0.00593727336679549,0.0774995035527617
2021-01-14 09:21:22,856;aequilibrae;INFO ; 32,0.006750405179915987,0.14899816317482056
2021-01-14 09:21:22,959;aequilibrae;INFO ; 33,0.005987462665246503,0.20531733943901
2021-01-14 09:21:23,063;aequilibrae;INFO ; 34,0.007500405203021081,0.3867491824211229
2021-01-14 09:21:23,169;aequilibrae;INFO ; 35,0.00807934806997432,0.04478012246532397
2021-01-14 09:21:23,273;aequilibrae;INFO ; 36,0.004545162238015598,0.05726713703214948
2021-01-14 09:21:23,379;aequilibrae;INFO ; 37,0.004618865645026883,0.06536522323014995
2021-01-14 09:21:23,485;aequilibrae;INFO ; 38,0.005010788012264289,0.11101405207807832
2021-01-14 09:21:23,590;aequilibrae;INFO ; 39,0.004396698580354392,0.1688370169872963
2021-01-14 09:21:23,695;aequilibrae;INFO ; 40,0.004230228229662576,0.28593375902854573
2021-01-14 09:21:23,801;aequilibrae;INFO ; 41,0.004161497833849531,0.43236082746717824
2021-01-14 09:21:23,908;aequilibrae;INFO ; 42,0.004229162946679855,0.4722194436765095
2021-01-14 09:21:24,015;aequilibrae;INFO ; 43,0.003976752865366218,0.014668379971974394
2021-01-14 09:21:24,119;aequilibrae;INFO ; 44,0.0028142070282866426,0.04166679258142381
2021-01-14 09:21:24,223;aequilibrae;INFO ; 45,0.0030542349122689065,0.04401630665257934
2021-01-14 09:21:24,327;aequilibrae;INFO ; 46,0.0028803666695939706,0.06646694571519754
2021-01-14 09:21:24,432;aequilibrae;INFO ; 47,0.0026603810561806993,0.074859543784368
2021-01-14 09:21:24,538;aequilibrae;INFO ; 48,0.002685166786325858,0.08413443815464196
2021-01-14 09:21:24,642;aequilibrae;INFO ; 49,0.0025193253855557043,0.12248606309947035
2021-01-14 09:21:24,745;aequilibrae;INFO ; 50,0.002018082135234086,0.0737435629848295
2021-01-14 09:21:24,849;aequilibrae;INFO ; 51,0.001955632691120813,0.052516904207595805
2021-01-14 09:21:24,952;aequilibrae;INFO ; 52,0.0017426875844649295,0.06135084119157079
2021-01-14 09:21:25,055;aequilibrae;INFO ; 53,0.001871698730713863,0.052968207332538986
2021-01-14 09:21:25,158;aequilibrae;INFO ; 54,0.0017946487943897138,0.10353271573469151
2021-01-14 09:21:25,261;aequilibrae;INFO ; 55,0.0017191753642994184,0.23999316419931338
2021-01-14 09:21:25,366;aequilibrae;INFO ; 56,0.002336619240598437,0.20303557937950142
2021-01-14 09:21:25,470;aequilibrae;INFO ; 57,0.0021101675696428876,0.30723326776889637
2021-01-14 09:21:25,573;aequilibrae;INFO ; 58,0.001805498707717509,0.5563829743009964
2021-01-14 09:21:25,679;aequilibrae;INFO ; 59,0.002204477565409996,0.006611138640252764
2021-01-14 09:21:25,782;aequilibrae;INFO ; 60,0.0010796716058064757,0.014043970280275353
2021-01-14 09:21:25,886;aequilibrae;INFO ; 61,0.0010152739547841475,0.020641521749009337
2021-01-14 09:21:25,989;aequilibrae;INFO ; 62,0.0011132821785653896,0.024854617511481013
2021-01-14 09:21:26,093;aequilibrae;INFO ; 63,0.0008581304000021201,0.016925541906281844
2021-01-14 09:21:26,197;aequilibrae;INFO ; 64,0.0006870136302672026,0.025612212755707478
2021-01-14 09:21:26,304;aequilibrae;INFO ; 65,0.0010887974102453072,0.03496791406330616
2021-01-14 09:21:26,409;aequilibrae;INFO ; 66,0.0012823296205770052,0.06544366784993504
2021-01-14 09:21:26,513;aequilibrae;INFO ; 67,0.0014107810433781015,0.07597489609127323
2021-01-14 09:21:26,618;aequilibrae;INFO ; 68,0.0014353199990589942,0.08829246547471065
2021-01-14 09:21:26,722;aequilibrae;INFO ; 69,0.0012760563867590517,0.06514075116523681
2021-01-14 09:21:26,828;aequilibrae;INFO ; 70,0.0007899350731351727,0.01261535393106658
2021-01-14 09:21:26,933;aequilibrae;INFO ; 71,0.0008296156361051738,0.01828614011809439
2021-01-14 09:21:27,037;aequilibrae;INFO ; 72,0.0007762313384011715,0.02023752730874635
2021-01-14 09:21:27,141;aequilibrae;INFO ; 73,0.0008854183017649134,0.03233339282539114
2021-01-14 09:21:27,245;aequilibrae;INFO ; 74,0.0008847279124070096,0.10639912316404641
2021-01-14 09:21:27,350;aequilibrae;INFO ; 75,0.0013039191419854264,0.08918595680975652
2021-01-14 09:21:27,453;aequilibrae;INFO ; 76,0.0011128232451419915,0.11526146328151711
2021-01-14 09:21:27,557;aequilibrae;INFO ; 77,0.0010758836276592231,0.06930417534943134
2021-01-14 09:21:27,661;aequilibrae;INFO ; 78,0.001018350489201382,0.05223780431249161
2021-01-14 09:21:27,766;aequilibrae;INFO ; 79,0.0008083495456310013,0.052241329775101694
2021-01-14 09:21:27,869;aequilibrae;INFO ; 80,0.0007824003605471833,0.02960806491851281
2021-01-14 09:21:27,973;aequilibrae;INFO ; 81,0.0007223585023863889,0.05528483835903717
2021-01-14 09:21:28,076;aequilibrae;INFO ; 82,0.0006432458866119056,0.05207309207277325
2021-01-14 09:21:28,182;aequilibrae;INFO ; 83,0.000595134464477738,0.03320548947415582
2021-01-14 09:21:28,285;aequilibrae;INFO ; 84,0.0005414782258271833,0.02413556768908468
2021-01-14 09:21:28,389;aequilibrae;INFO ; 85,0.0006761686264139118,0.05514566368863905
2021-01-14 09:21:28,493;aequilibrae;INFO ; 86,0.0005657048099061215,0.04598750778616338
2021-01-14 09:21:28,596;aequilibrae;INFO ; 87,0.0005719659722018737,0.024733661631380115
2021-01-14 09:21:28,702;aequilibrae;INFO ; 88,0.0005162686019636334,0.08905862320006376
2021-01-14 09:21:28,805;aequilibrae;INFO ; 89,0.0007159916325059481,0.1057212796605331
2021-01-14 09:21:28,909;aequilibrae;INFO ; 90,0.0008132971301132341,0.12200583241654034
2021-01-14 09:21:29,012;aequilibrae;INFO ; 91,0.0007337315079824217,0.053556626383897805
2021-01-14 09:21:29,116;aequilibrae;INFO ; 92,0.0007294750580059871,0.10238103118171861
2021-01-14 09:21:29,221;aequilibrae;INFO ; 93,0.0006907145032491211,0.05199426817350668
2021-01-14 09:21:29,324;aequilibrae;INFO ; 94,0.000590322065818312,0.05612654538471275
2021-01-14 09:21:29,431;aequilibrae;INFO ; 95,0.0004037741309954399,0.0130275630798323
2021-01-14 09:21:29,535;aequilibrae;INFO ; 96,0.00032767309446119435,0.058428496798429985
2021-01-14 09:21:29,640;aequilibrae;INFO ; 97,0.0003024021037035998,0.019268785049975985
2021-01-14 09:21:29,747;aequilibrae;INFO ; 98,0.0002755559866524671,0.04166083096014988
2021-01-14 09:21:29,852;aequilibrae;INFO ; 99,0.00037356495445535444,0.03177131972259261
2021-01-14 09:21:29,956;aequilibrae;INFO ; 100,0.0003138297718779111,0.020288036121870395
2021-01-14 09:21:30,062;aequilibrae;INFO ; 101,0.00025620095719622733,0.018453985263577406
2021-01-14 09:21:30,166;aequilibrae;INFO ; 102,0.00023730091836960838,0.00963149816426395
2021-01-14 09:21:30,270;aequilibrae;INFO ; 103,0.00020666661953792277,0.008263891778262426
2021-01-14 09:21:30,374;aequilibrae;INFO ; 104,0.0002416007586114039,0.018624442895068923
2021-01-14 09:21:30,478;aequilibrae;INFO ; 105,0.0002488252236903022,0.018664968656614093
2021-01-14 09:21:30,582;aequilibrae;INFO ; 106,0.0002729643360314989,0.025208444738771128
2021-01-14 09:21:30,686;aequilibrae;INFO ; 107,0.0003879947356031886,0.05647499623776948
2021-01-14 09:21:30,790;aequilibrae;INFO ; 108,0.0004173424979260342,0.056568920847935855
2021-01-14 09:21:30,897;aequilibrae;INFO ; 109,0.00043630800233183985,0.10555010329730016
2021-01-14 09:21:31,004;aequilibrae;INFO ; 110,0.0005468715527371659,0.15561823623384466
2021-01-14 09:21:31,110;aequilibrae;INFO ; 111,0.0006167293208744864,0.22028767419088705
2021-01-14 09:21:31,214;aequilibrae;INFO ; 112,0.0005427370494637428,0.18379917813832777
2021-01-14 09:21:31,317;aequilibrae;INFO ; 113,0.00042872524519178823,0.14269697546231452
2021-01-14 09:21:31,421;aequilibrae;INFO ; 114,0.0003272617760800179,0.042515681128095
2021-01-14 09:21:31,525;aequilibrae;INFO ; 115,0.0003030636798404827,0.07190276805332359
2021-01-14 09:21:31,631;aequilibrae;INFO ; 116,0.0002780564282139639,0.049487968795499826
2021-01-14 09:21:31,734;aequilibrae;INFO ; 117,0.00022008472327203962,0.026090437647600162
2021-01-14 09:21:31,838;aequilibrae;INFO ; 118,0.0002564875937952469,0.05099087992961783
2021-01-14 09:21:31,942;aequilibrae;INFO ; 119,0.00020594692207321675,0.02707256554478107
2021-01-14 09:21:32,046;aequilibrae;INFO ; 120,0.0002484835343536905,0.02833412601815026
2021-01-14 09:21:32,150;aequilibrae;INFO ; 121,0.0002664679646692054,0.043104481501559905
2021-01-14 09:21:32,254;aequilibrae;INFO ; 122,0.00018208191669150716,0.027269282263367698
2021-01-14 09:21:32,357;aequilibrae;INFO ; 123,0.0001882297443439262,0.02727632842404067
2021-01-14 09:21:32,461;aequilibrae;INFO ; 124,0.00018563819740245234,0.03906959081463374
2021-01-14 09:21:32,565;aequilibrae;INFO ; 125,0.0002043486269125215,0.04821497169181341
2021-01-14 09:21:32,669;aequilibrae;INFO ; 126,0.0003275508037349304,0.04654582969174732
2021-01-14 09:21:32,775;aequilibrae;INFO ; 127,0.00021211746699955817,0.02351406437037179
2021-01-14 09:21:32,882;aequilibrae;INFO ; 128,0.00016400322233737637,0.031198785422996082
2021-01-14 09:21:32,986;aequilibrae;INFO ; 129,0.0001678153937209772,0.027803331293167963
2021-01-14 09:21:33,092;aequilibrae;INFO ; 130,0.00019793203180543012,0.02341693729708396
2021-01-14 09:21:33,197;aequilibrae;INFO ; 131,0.00015088510634232965,0.018492960014886806
2021-01-14 09:21:33,304;aequilibrae;INFO ; 132,0.00011405411364788738,0.0077301118298239374
2021-01-14 09:21:33,409;aequilibrae;INFO ; 133,0.0001054661846999205,0.011380967982069591
2021-01-14 09:21:33,516;aequilibrae;INFO ; 134,0.0001331959763815773,0.008500483941211234
2021-01-14 09:21:33,622;aequilibrae;INFO ; 135,0.00014406849320655791,0.01611905888813753
2021-01-14 09:21:33,726;aequilibrae;INFO ; 136,0.00012762537867671726,0.009039456597316638
2021-01-14 09:21:33,829;aequilibrae;INFO ; 137,0.00017684354721467075,0.025606789776217456
2021-01-14 09:21:33,933;aequilibrae;INFO ; 138,0.00018404053296946197,0.03157952156714524
2021-01-14 09:21:34,039;aequilibrae;INFO ; 139,0.00017545442214480413,0.0358769692637386
2021-01-14 09:21:34,145;aequilibrae;INFO ; 140,0.00015232784948427137,0.039854332206721396
2021-01-14 09:21:34,250;aequilibrae;INFO ; 141,0.00015019606703790052,0.025741791753486558
2021-01-14 09:21:34,354;aequilibrae;INFO ; 142,0.00015297185673032477,0.03227353696620909
2021-01-14 09:21:34,458;aequilibrae;INFO ; 143,0.00014804749885478444,0.03185643267983867
2021-01-14 09:21:34,566;aequilibrae;INFO ; 144,0.0001346150626565754,0.023176085919719924
2021-01-14 09:21:34,670;aequilibrae;INFO ; 145,0.0001258620390022246,0.029862812877762716
2021-01-14 09:21:34,774;aequilibrae;INFO ; 146,0.00011661702168451547,0.029510905006759857
2021-01-14 09:21:34,877;aequilibrae;INFO ; 147,0.00011541801986773167,0.02267872074249115
2021-01-14 09:21:34,983;aequilibrae;INFO ; 148,0.00013633485378199633,0.027885568953428096
2021-01-14 09:21:35,089;aequilibrae;INFO ; 149,0.00014420953979751692,0.0301126891073716
2021-01-14 09:21:35,194;aequilibrae;INFO ; 150,0.00010113451658552998,0.023672744966317636
2021-01-14 09:21:35,298;aequilibrae;INFO ; 151,0.00011226562488406831,0.04401370112461414
2021-01-14 09:21:35,404;aequilibrae;INFO ; 152,0.00014305929266108866,0.09150381207571148
2021-01-14 09:21:35,511;aequilibrae;INFO ; 153,0.00015643402561697187,0.058579524668762914
2021-01-14 09:21:35,615;aequilibrae;INFO ; 154,9.945828619312398e-05,0.037559145442319794
2021-01-14 09:21:35,721;aequilibrae;INFO ; 155,0.00010879259092747432,0.021452844621657252
2021-01-14 09:21:35,824;aequilibrae;INFO ; 156,0.00012240647392431373,0.0510928332899237
2021-01-14 09:21:35,931;aequilibrae;INFO ; 157,0.00015294457120250009,0.037091779377233194
2021-01-14 09:21:36,036;aequilibrae;INFO ; 158,0.00012307570493557668,0.08122859647394275
2021-01-14 09:21:36,142;aequilibrae;INFO ; 159,0.0002075971226303054,0.04805396969782005
2021-01-14 09:21:36,248;aequilibrae;INFO ; 160,0.0001224636704136417,0.024568857577673447
2021-01-14 09:21:36,354;aequilibrae;INFO ; 161,0.0001320497727780432,0.01993516732078519
2021-01-14 09:21:36,458;aequilibrae;INFO ; 162,0.00010925270470463269,0.03929653776092544
2021-01-14 09:21:36,562;aequilibrae;INFO ; 163,0.00012257749957519422,0.01897110937044076
2021-01-14 09:21:36,665;aequilibrae;INFO ; 164,0.00010523477276794625,0.03447084314103723
2021-01-14 09:21:36,769;aequilibrae;INFO ; 165,0.00010499061610554204,0.020004214116470596
2021-01-14 09:21:36,875;aequilibrae;INFO ; 166,0.00015246595292907507,0.07007283298943794
2021-01-14 09:21:36,980;aequilibrae;INFO ; 167,0.00012291721240238965,0.04691924709248544
2021-01-14 09:21:37,084;aequilibrae;INFO ; 168,0.00010908307127939226,0.04664924229249563
2021-01-14 09:21:37,187;aequilibrae;INFO ; 169,9.080082437054021e-05,0.02284914418873871
2021-01-14 09:21:37,188;aequilibrae;INFO ; bfw Assignment finished. 169 iterations and 9.080082437054021e-05 final gap
# 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')

Out:

2021-01-14 09:21:37,391;aequilibrae;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()
plot forecasting

Close the project

project.close()

Out:

2021-01-14 09:21:37,980;aequilibrae;INFO ; Closed project on /tmp/a1e1037fb5ce4aed8ff7cd8d34787895

Total running time of the script: ( 0 minutes 26.804 seconds)

Gallery generated by Sphinx-Gallery