Skip to content

Commit

Permalink
update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
r-akemii committed Sep 12, 2024
1 parent 685c3ff commit c7e9fbc
Show file tree
Hide file tree
Showing 10 changed files with 112 additions and 145 deletions.
97 changes: 53 additions & 44 deletions aequilibrae/paths/route_choice.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,46 +81,49 @@ def set_choice_set_generation(self, /, algorithm: str, **kwargs) -> None:
Options for algorithm are, 'bfsle' for breadth first search with link removal, or
'link-penalisation'/'link-penalization'.
BFSLE implementation based on "Route choice sets for very high-resolution data" by Nadine Rieser-Schüssler,
Michael Balmer & Kay W. Axhausen (2013).
https://doi.org/10.1080/18128602.2012.671383
BFSLE implementation based on "Route choice sets for very high-resolution data" by
Nadine Rieser-Schüssler, Michael Balmer & Kay W. Axhausen (2013).
`DOI: 10.1080/18128602.2012.671383 <https://doi.org/10.1080/18128602.2012.671383>`_.
'lp' is also accepted as an alternative to 'link-penalisation'
Setting the parameters for the route choice:
`seed` is a BFSLE specific parameters.
``seed`` is a BFSLE specific parameters.
Setting `max_depth` or `max_misses`, while not required, is strongly recommended to prevent runaway algorithms.
`max_misses` is the maximum amount of duplicate routes found per OD pair. If it is exceeded then the route set
if returned with fewer than `max_routes`. It has a default value of `100`.
Setting ``max_depth`` or ``max_misses``, while not required, is strongly recommended to prevent runaway
algorithms.
- When using BFSLE `max_depth` corresponds to the maximum height of the graph of graphs. It's value is
largely dependent on the size of the paths within the network. For very small networks a value of 10
is a recommended starting point. For large networks a good starting value is 5. Increase the value
``max_misses`` is the maximum amount of duplicate routes found per OD pair. If it is exceeded then the route set
if returned with fewer than ``max_routes``. It has a default value of ``100``.
- When using **BFSLE** ``max_depth`` corresponds to the maximum height of the graph of graphs. It's value is
largely dependent on the size of the paths within the network. For very small networks a value of ``10``
is a recommended starting point. For large networks a good starting value is ``5``. Increase the value
until the number of desired routes is being consistently returned. If it is exceeded then the route set
if returned with fewer than `max_routes`.
if returned with fewer than ``max_routes``.
- When using LP, `max_depth` corresponds to the maximum number of iterations performed. While not enforced,
it should be higher than `max_routes`. It's value is dependent on the magnitude of the cost field,
specifically it's related to the log base `penalty` of the ratio of costs between two alternative routes.
If it is exceeded then the route set if returned with fewer than `max_routes`.
- When using **LP**, ``max_depth`` corresponds to the maximum number of iterations performed. While not
enforced,
it should be higher than ``max_routes``. It's value is dependent on the magnitude of the cost field,
specifically it's related to the log base ``penalty`` of the ratio of costs between two alternative routes.
If it is exceeded then the route set if returned with fewer than ``max_routes``.
Additionally BFSLE has the option to incorporate link penalisation. Every link in all routes found at a depth
are penalised with the `penalty` factor for the next depth. So at a depth of 0 no links are penalised nor
removed. At depth 1, all links found at depth 0 are penalised, then the links marked for removal are removed.
All links in the routes found at depth 1 are then penalised for the next depth. The penalisation compounds.
Pass set `penalty=1.0` to disable.
are penalised with the ``penalty`` factor for the next depth. So at a depth of ``0`` no links are penalised nor
removed. At depth ``1``, all links found at depth 0 are penalised, then the links marked for removal are removed.
All links in the routes found at depth ``1`` are then penalised for the next depth. The penalisation compounds.
Pass set ``penalty=1.0`` to disable.
When performing an assignment, `cutoff_prob` can be provided to exclude routes from the path-sized logit model.
The `cutoff_prob` is used to compute an inverse binary logit and obtain a max difference in utilities. If a
When performing an assignment, ``cutoff_prob`` can be provided to exclude routes from the path-sized logit model.
The ``cutoff_prob`` is used to compute an inverse binary logit and obtain a max difference in utilities. If a
paths total cost is greater than the minimum cost path in the route set plus the max difference, the route is
excluded from the PSL calculations. The route is still returned, but with a probability of 0.0.
The `cutoff_prob` should be in the range [0, 1]. It is then rescaled internally to [0.5, 1] as probabilities
below 0.5 produce negative differences in utilities because the choice is between two routes only, one of
which is the shortest path. A higher `cutoff_prob` includes less routes. A value of `1.0` will only include
the minimum cost route. A value of `0.0` includes all routes.
The ``cutoff_prob`` should be in the range :math:`[0, 1]`. It is then rescaled internally to :math:`[0.5, 1]` as probabilities
below ``0.5`` produce negative differences in utilities because the choice is between two routes only, one of
which is the shortest path. A higher ``cutoff_prob`` includes less routes. A value of ``1.0`` will only include
the minimum cost route. A value of ``0.0`` includes all routes.
:Arguments:
**algorithm** (:obj:`str`): Algorithm to be used
Expand Down Expand Up @@ -190,10 +193,10 @@ def add_demand(self, demand, fill: float = 0.0):
:Arguments:
**demand** (:obj:`Union[pd.DataFrame, AequilibraeMatrix]`): Demand to add to assignment. If the supplied
demand is a DataFrame, it should have a 2-level MultiIndex of Origin and Destination node IDs. If an
AequilibraE matrix is supplied node IDs will be inferred from the index. Demand values should be either
float32s or float64s.
AequilibraE Matrix is supplied node IDs will be inferred from the index. Demand values should be either
``float32``s or ``float64``s.
**fill** (:obj:`float`): Value to fill any NaNs with.
**fill** (:obj:`float`): Value to fill any ``NaN``s with.
"""
if isinstance(demand, pd.DataFrame):
self.demand.add_df(demand, fill=fill)
Expand All @@ -211,7 +214,7 @@ def prepare(self, nodes: Union[List[int], List[Tuple[int, int]], None] = None) -
provided, OD pairs are taken to be all pair permutations of the list. If a list of pairs is provided
OD pairs are taken as is. All node IDs must be present in the compressed graph. To make a node ID
always appear in the compressed graph add it as a centroid. Duplicates will be dropped on execution.
If *None* is provided, all OD pairs with non-zero flows will be used.
If ``None`` is provided, all OD pairs with non-zero flows will be used.
"""
if nodes is not None and not self.demand.no_demand():
raise ValueError("provide either `nodes` or set a `demand` matrix, not both")
Expand Down Expand Up @@ -276,10 +279,10 @@ def execute(self, perform_assignment: bool = True) -> None:
"""
Generate route choice sets between the previously supplied nodes, potentially performing an assignment.
To access results see `RouteChoice.get_results()`.
To access results see ``RouteChoice.get_results()``.
:Arguments:
**perform_assignment** (:obj:`bool`): Whether or not to perform an assignment. Default `False`.
**perform_assignment** (:obj:`bool`): Whether or not to perform an assignment. Defaults to ``False``.
"""
if self.demand.df.index.empty:
logging.warning("There is no demand or pairs of OD pairs to compute Route choice for.")
Expand All @@ -301,11 +304,11 @@ def execute(self, perform_assignment: bool = True) -> None:
def info(self) -> dict:
"""Returns information for the transit assignment procedure
Dictionary contains keys 'Algorithm', 'Matrix totals', 'Computer name', 'Procedure ID', 'Parameters', and
Dictionary contains keys 'Algorithm', 'Matrix totals', 'Computer name', 'Procedure ID', 'Parameters', and
'Select links'.
The classes key is also a dictionary with all the user classes per transit class and their respective
matrix totals
matrix totals.
:Returns:
**info** (:obj:`dict`): Dictionary with summary information
Expand Down Expand Up @@ -333,7 +336,7 @@ def get_results(self) -> Union[pa.Table, pa.dataset.Dataset]:
Returns a table of OD pairs to lists of link IDs for each OD pair provided (as columns).
Represents paths from ``origin`` to ``destination``.
If `save_routes` was specified then a Pyarrow dataset is returned. The caller is responsible for reading this
If ``save_routes`` was specified then a Pyarrow dataset is returned. The caller is responsible for reading this
dataset.
:Returns:
Expand All @@ -351,8 +354,8 @@ def get_load_results(self) -> pd.DataFrame:
Translates the link loading results from the graph format into the network format.
:Returns:
**dataset** (:obj:`Union[Tuple[pd.DataFrame, pd.DataFrame], pd.DataFrame]`):
A tuple of link loading results as DataFrames. Columns are the matrix name concatenated direction.
**dataset** (:obj:`Union[Tuple[pd.DataFrame, pd.DataFrame], pd.DataFrame]`): A tuple of link loading
results as DataFrames. Columns are the matrix name concatenated direction.
"""

if self.demand.no_demand():
Expand Down Expand Up @@ -390,19 +393,25 @@ def set_select_links(
self, links: Dict[Hashable, List[Union[Tuple[int, int], List[Tuple[int, int]]]]], link_loading=True
):
"""
Set the selected links. Checks if the links and directions are valid. Supports OR and AND sets of links.
Set the selected links. Checks if the links and directions are valid. Supports **OR** and **AND** sets of links.
Dictionary values should be a list of either a single ``(link_id, direction)`` tuple or a list of
``(link_id, dirirection)``.
Dictionary values should be a list of either (link_id, dir) or a list of (link_id, dir).
The elements of the first list represent the **AND** sets, together they are OR'ed. If any of these sets is
satisfied the link are loaded as appropriate.
The **AND** sets are comprised of either a single ``(link_id, direction)`` tuple or a list of
``(link_id, direction)``. The single tuple represents an **AND** set with a single element.
All links and directions in an **AND** set must appear in any order within a route for it to be considered
satisfied.
The elements of the first list represent the AND sets, together they are OR'ed. If any of these sets is
satisfied the link are loaded as appropriate. The AND sets are comprised of either a single (link_id, dir) tuple
or a list of (link_id, dir). The single tuple represents an AND set with a single element. All links and
directions in an AND set must appear in any order within a route for it to be considered satisfied.
Supply `links=None` to disable select link analysis.
Supply ``links=None`` to disable select link analysis.
:Arguments:
**links** (:obj:`Union[None, Dict[Hashable, List[Union[Tuple[int, int], List[Tuple[int, int]]]]]]`):
Name of link set and Link IDs and directions to be used in select link analysis.
Name of link set and link IDs and directions to be used in select link analysis.
**link_loading** (:obj:`bool`): Enable select link loading. If disabled only OD matrix results are
available.
Expand Down
4 changes: 2 additions & 2 deletions aequilibrae/paths/sub_area.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ def __init__(
:Arguments:
**graph** (:obj:`Graph`): AequilibraE graph object to use
**subarea** (:obj:`gpd.GeoDataFrame`): A GeoPandas GeoDataFrame whose geometry union represents the
sub-area.
**demand** (:obj:`Union[pandas.DataFrame, AequilibraeMatrix]`): The demand matrix to provide to the route
choice assignment.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import os
import pandas as pd
import numpy as np
from uuid import uuid4
from tempfile import gettempdir

from aequilibrae.matrix import AequilibraeMatrix
Expand All @@ -32,7 +33,7 @@

# %%
# Let's use a temporary folder to store our data
folder = gettempdir()
folder = os.path.join(gettempdir(), uuid4().hex)

# %%
# First we load our demand file. This file has three columns: O, D, and Ton.
Expand All @@ -55,8 +56,7 @@
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
'matrix_names': ['matrix']}

aem.create_empty(**kwargs)
aem.matrix['matrix'][:,:] = mtx[:,:]
Expand Down Expand Up @@ -106,12 +106,12 @@
g.lonlat_index = geom.loc[g.all_nodes]

# %%
# Let's perform our assignment. Feel free to try different algorithms,
# as well as change the maximum number of iterations and the gap.
aem = AequilibraeMatrix()
aem.load(aemfile)
# Let's prepare our matrix for computation
aem.computational_view(["matrix"])

# %%
# Let's perform our assignment. Feel free to try different algorithms,
# as well as change the maximum number of iterations and the gap
assigclass = TrafficClass("car", g, aem)

assig = TrafficAssignment()
Expand All @@ -128,11 +128,11 @@

# %%
# Now let's take a look at the Assignment results
print(assig.results())
assig.results()

# %%
# And at the Assignment report
print(assig.report())
assig.report()

# %%
# .. admonition:: References
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
========================================
In this example, we show you how to use AequilibraE's IPF function without a model.
This is a compliment to the application in :ref:`Trip Distribution <example_usage_distribution>`.
This is a complement to the application in :ref:`example_usage_forecasting`.
Let's consider that you have an OD-matrix, the future production and future attraction values.
*How would your trip distribution matrix using IPF look like?*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ def plot_tlfd(demand, skim, name):
#
# The string name will name the set of links, and the list of tuples is the list of selected links
# in the form ``(link_id, direction)``, as it occurs in the :ref:`Graph <aequilibrae-graphs>`.
#
# Direction can be one of ``0``, ``1``, ``-1``, where ``0`` denotes bi-directionality.

# %%
Expand Down
Loading

0 comments on commit c7e9fbc

Please sign in to comment.