Traffic Assignment without an AequilibraE Model#

In this example, we show how to perform Traffic Assignment in AequilibraE without a model.

We are using Sioux Falls data, from TNTP.

Imports

[1]:
import os
import pandas as pd
import numpy as np
from tempfile import gettempdir

from aequilibrae.matrix import AequilibraeMatrix
from aequilibrae.paths import Graph
from aequilibrae.paths import TrafficAssignment
from aequilibrae.paths.traffic_class import TrafficClass

We load the example file from the GMNS GitHub repository

[2]:
net_file = "https://raw.githubusercontent.com/bstabler/TransportationNetworks/master/SiouxFalls/SiouxFalls_net.tntp"

demand_file = "https://raw.githubusercontent.com/bstabler/TransportationNetworks/master/SiouxFalls/CSV-data/SiouxFalls_od.csv"

Let’s use a temporary folder to store our data

[3]:
folder = gettempdir()

First we load our demand file. This file has three columns: O, D, and Ton. O and D stand for origin and destination, respectively, and Ton is the demand of each OD pair.

[4]:
dem = pd.read_csv(demand_file)
zones = int(max(dem.O.max(), dem.D.max()))
index = np.arange(zones) + 1

Since our OD-matrix is in a different shape than we expect (for Sioux Falls, that would be a 24x24 matrix), we must create our matrix.

[5]:
mtx = np.zeros(shape=(zones, zones))
for element in dem.to_records(index=False):
    mtx[element[0]-1][element[1]-1] = element[2]

Now let’s create an AequilibraE Matrix with out data

[6]:
aemfile = os.path.join(folder, "demand.aem")
aem = AequilibraeMatrix()
kwargs = {'file_name': aemfile,
          'zones': zones,
          'matrix_names': ['matrix'],
          "memory_only": False}  # We'll save it to disk so we can use it later

aem.create_empty(**kwargs)
aem.matrix['matrix'][:,:] = mtx[:,:]
aem.index[:] = index[:]

Let’s import information about our network. As we’re loading data in TNTP format, we should do these manipulations.

[7]:
net = pd.read_csv(net_file, skiprows=2, sep="\t", lineterminator=";", header=None)

net.columns = ["newline", "a_node", "b_node", "capacity", "length", "free_flow_time", "b", "power", "speed", "toll", "link_type", "terminator"]

net.drop(columns=["newline", "terminator"], index=[76], inplace=True)
[8]:
network = net[['a_node', 'b_node', "capacity", 'free_flow_time', "b", "power"]]
network = network.assign(direction=1)
network["link_id"] = network.index + 1
network = network.astype({"a_node":"int64", "b_node": "int64"})

Let’s build our Graph! In case you’re in doubt about the Graph, click here <aequilibrae-graphs> to read more about it. %%

[9]:
g = Graph()
g.cost = network['free_flow_time'].values
g.capacity = network['capacity'].values
g.free_flow_time = network['free_flow_time'].values

g.network = network
g.network_ok = True
g.status = 'OK'
g.prepare_graph(index)
g.set_graph("free_flow_time")
g.cost = np.array(g.cost, copy=True)
g.set_skimming(["free_flow_time"])
g.set_blocked_centroid_flows(False)
g.network["id"] = g.network.link_id

Let’s perform our assignment. Feel free to try different algorithms, as well as change the maximum number of iterations and the gap.

[10]:
aem = AequilibraeMatrix()
aem.load(aemfile)
aem.computational_view(["matrix"])

assigclass = TrafficClass("car", g, aem)

assig = TrafficAssignment()

assig.set_classes([assigclass])
assig.set_vdf("BPR")
assig.set_vdf_parameters({"alpha": "b", "beta": "power"})
assig.set_capacity_field("capacity")
assig.set_time_field("free_flow_time")
assig.set_algorithm("fw")
assig.max_iter = 100
assig.rgap_target = 1e-6
assig.execute()

Now let’s take a look at the Assignment results

[11]:
print(assig.results())
            matrix_ab  matrix_ba    matrix_tot  Congested_Time_AB  \
link_id
1         4532.416460        NaN   4532.416460           6.000844
2         8124.962104        NaN   8124.962104           4.008716
3         4528.444976        NaN   4528.444976           6.000841
4         6001.323525        NaN   6001.323525           6.609756
5         8128.933588        NaN   8128.933588           4.008733
...               ...        ...           ...                ...
72        9643.868005        NaN   9643.868005          12.303788
73        7855.662507        NaN   7855.662507           3.717544
74       11101.449987        NaN  11101.449987          17.563454
75       10255.489839        NaN  10255.489839          11.738819
76        7923.866336        NaN   7923.866336           3.777973

         Congested_Time_BA  Congested_Time_Max  Delay_factor_AB  \
link_id
1                      NaN            6.000844         1.000141
2                      NaN            4.008716         1.002179
3                      NaN            6.000841         1.000140
4                      NaN            6.609756         1.321951
5                      NaN            4.008733         1.002183
...                    ...                 ...              ...
72                     NaN           12.303788         3.075947
73                     NaN            3.717544         1.858772
74                     NaN           17.563454         4.390863
75                     NaN           11.738819         3.912940
76                     NaN            3.777973         1.888986

         Delay_factor_BA  Delay_factor_Max    VOC_AB  VOC_BA   VOC_max  \
link_id
1                    NaN          1.000141  0.174995     NaN  0.174995
2                    NaN          1.002179  0.347169     NaN  0.347169
3                    NaN          1.000140  0.174842     NaN  0.174842
4                    NaN          1.321951  1.210388     NaN  1.210388
5                    NaN          1.002183  0.347339     NaN  0.347339
...                  ...               ...       ...     ...       ...
72                   NaN          3.075947  1.928774     NaN  1.928774
73                   NaN          1.858772  1.546844     NaN  1.546844
74                   NaN          4.390863  2.180493     NaN  2.180493
75                   NaN          3.912940  2.099230     NaN  2.099230
76                   NaN          1.888986  1.560274     NaN  1.560274

               PCE_AB  PCE_BA       PCE_tot
link_id
1         4532.416460     NaN   4532.416460
2         8124.962104     NaN   8124.962104
3         4528.444976     NaN   4528.444976
4         6001.323525     NaN   6001.323525
5         8128.933588     NaN   8128.933588
...               ...     ...           ...
72        9643.868005     NaN   9643.868005
73        7855.662507     NaN   7855.662507
74       11101.449987     NaN  11101.449987
75       10255.489839     NaN  10255.489839
76        7923.866336     NaN   7923.866336

[76 rows x 15 columns]

And at the Assignment report

[12]:
print(assig.report())
    iteration      rgap     alpha warnings
0           1       inf  1.000000
1           2  0.855131  0.328177
2           3  0.476738  0.186185
3           4  0.239622  0.229268
4           5  0.139851  0.314341
..        ...       ...       ...      ...
95         96  0.001999  0.011309
96         97  0.001431  0.006948
97         98  0.001405  0.014356
98         99  0.001814  0.012088
99        100  0.001577  0.007687

[100 rows x 4 columns]