Skip to content

Commit a3ec1e9

Browse files
committed
update README on time-dependent accessibility
- update docstrings in accessibility.py and classes.py as well; - add demo code to demo.py.
1 parent 2076967 commit a3ec1e9

File tree

5 files changed

+231
-44
lines changed

5 files changed

+231
-44
lines changed

README.md

Lines changed: 68 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,16 @@ Path4GMNS also serves as an API to the C++-based [DTALite](https://github.com/jd
1414
* Origin-Destination Matrix Estimation (ODME).
1515

1616
## Installation
17-
Path4GMNS has been published on [PyPI](https://pypi.org/project/path4gmns/0.7.2/), and can be installed using
17+
Path4GMNS has been published on [PyPI](https://pypi.org/project/path4gmns/0.7.3/), and can be installed using
1818
```
1919
$ pip install path4gmns
2020
```
21-
If you need a specific version of Path4GMNS, say, 0.7.2,
21+
If you need a specific version of Path4GMNS, say, 0.7.3,
2222
```
23-
$ pip install path4gmns==0.7.2
23+
$ pip install path4gmns==0.7.3
2424
```
2525

26-
v0.7.2 comes with bug fixes, new functionalities, and new interfaces. All previous releases shall be deprecated for any purposes.
26+
v0.7.3 comes with bug fixes and new functionalities. All previous releases shall be deprecated for any purposes.
2727

2828
### Dependency
2929
The Python modules are written in **Python 3.x**, which is the minimum requirement to explore the most of Path4GMNS. Some of its functions require further run-time support, which we will go through along with the corresponding use cases in the following section.
@@ -66,7 +66,7 @@ print('\nshortest path (link id) from node 1 to node 2, '
6666
+network.find_shortest_path(1, 2, 'link'))
6767
```
6868

69-
Retrieving the shortest path between any two (different) nodes under a specific mode is now available under v0.7.2.
69+
Retrieving the shortest path between any two (different) nodes under a specific mode is now available under v0.7.2 or higher.
7070
```python
7171
import path4gmns as pg
7272

@@ -116,7 +116,7 @@ print('shortest path (link id) of agent, '
116116
pg.output_agent_paths(network)
117117
```
118118

119-
v0.7.2 features finding agent paths under a specific mode defined in settings.yaml. The following example demostrates this new functionality under mode walk (i.e., w).
119+
v0.7.2 or higher features finding agent paths under a specific mode defined in settings.yaml. The following example demostrates this new functionality under mode walk (i.e., w).
120120
```python
121121
import path4gmns as pg
122122

@@ -126,7 +126,7 @@ network.find_path_for_agents()
126126
# or equivalently network.find_path_for_agents('walk')
127127
network.find_path_for_agents('w')
128128

129-
# retrieving the origin, the destination, and the shortest path of a given agent
129+
# retrieving the origin, the destination, and the shortest path of a given agent
130130
# is exactly the same as before as well as outputing all unique agent paths
131131
```
132132

@@ -268,7 +268,7 @@ print('complete accessibility evaluation.\n')
268268
print(f'processing time of accessibility evaluation: {time()-st:.2f} s')
269269
```
270270
271-
Two formats of accessibility will be outputed: accessibility between each OD pair in terms of free flow travel time (accessibility.csv) and aggregated accessibility as to the number of accessible zones from each zone for each transportation mode specified in settings.yml given a budget time (up to 240 minutes) (accessibility_aggregated.csv). The following example is to evaluate accessibility only under the default mode (i.e. mode auto or agent type passenger).
271+
Two formats of accessibility will be outputed: accessibility between each OD pair in terms of free flow travel time (accessibility.csv) and aggregated accessibility as to the number of accessible zones from each zone for each transportation mode specified in settings.yml given a budget time (up to 240 minutes) (accessibility_aggregated.csv). The following example is to evaluate accessibility only under the default mode (i.e., mode auto or agent type passenger).
272272
273273
```python
274274
import path4gmns as pg
@@ -311,6 +311,60 @@ network.get_accessible_links(1, 15, 'w')
311311
# network.get_accessible_links(1, 15, 'walk')
312312
```
313313

314+
### When Time-Dependent Link Travel Time Matters
315+
Link travel time is crucial in calculating accessibility. In the classic accessibility analysis, evalutaion networks are usually considered to be static in terms of link travel time, which is determined by link length and link free-flow speed under a specific mode. The free-flow speed comes from either link.csv or settings.yml (both are denoted as 'free_speed'). When they are different, the minimum of these two will be adopted. The cases demonstrated above are all falling within this category.
316+
317+
Link travel time varies over time so does accessibility. When the time-dependent accessibility is of interested, time-dependent link travel time (i.e., VDF_fftt from a given demand period in link.csv) will come into play by overwriting the static link free-flow speed above. This new feature is now part of v0.7.3 and is illustrated as below.
318+
319+
```python
320+
import path4gmns as pg
321+
322+
# no need to load demand file for accessibility evaluation
323+
network = pg.read_network(load_demand=False)
324+
325+
print('\nstart accessibility evaluation\n')
326+
st = time()
327+
328+
# time-dependent accessibility under the default mode auto (i.e., p)
329+
# for demand period 0 (i.e., VDF_fftt1 in link.csv will be used in the evaluation)
330+
pg.evaluate_accessiblity(network, multimodal=False, time_dependent=True)
331+
332+
# if you would like to evaluate accessibility under a different demand period
333+
# (say 1, which must be defined in settings.yml along with VDF_fftt2 in link.csv), then
334+
# pg.evaluate_accessiblity(network, multimodal=False, time_dependent=True, demand_period_id=1)
335+
336+
# if you would like to evaluate accessibility under a target mode, say walk, then
337+
# pg.evaluate_accessibility(network, multimodal=False, mode='w', time_dependent=True)
338+
# or equivalently pg.evaluate_accessibility(network, multimodal=False, mode='walk', time_dependent=True)
339+
340+
print('complete accessibility evaluation.\n')
341+
print(f'processing time of accessibility evaluation: {time()-st:.2f} s')
342+
```
343+
344+
While VDF_fftt begins with 1 (i.e., VDF_fftt1), the argument demand_period_id, corresponding to the sequence number of demand period appeared in demand_periods in settings.yml, starts from 0. So 'demand_period_id=1' indicates that 'VDF_fftt2' will be used.
345+
346+
**As VDF_fftt in link.csv can only accommodate one mode, time-dependent accessibility evaluation will require the user to prepare mode-specific link.csv with dedicated VDF_fftt and allowed_uses**. That's the reason that multimodal=False is always enforced in these examples.
347+
348+
Retrieve the time-dependent accessible nodes and links is similar to evaluate time-dependent accessibility by simply passing time_dependent and demand_period_id to get_accessible_nodes() and get_accessible_links()
349+
```python
350+
import path4gmns as pg
351+
352+
# no need to load demand file for accessibility evaluation
353+
network = pg.read_network(load_demand=False)
354+
355+
# get accessible nodes and links starting from node 1 with a 5-minitue
356+
# time window for the default mode auto (i.e., 'p') for demand period 0
357+
network.get_accessible_nodes(1, 5, time_dependent=True)
358+
# get accessible nodes and links starting from node 1 with a 5-minitue
359+
# time window for the default mode auto (i.e., 'p') for demand period 1 if it is defined
360+
network.get_accessible_links(1, 5, time_dependent=True, demand_period_id=1)
361+
362+
# get accessible nodes and links starting from node 1 with a 15-minitue
363+
# time window for mode walk (i.e., 'w') for demand periods 0 and 1 respectively
364+
network.get_accessible_nodes(1, 15, 'w', time_dependent=True)
365+
network.get_accessible_links(1, 15, 'w', time_dependent=True, demand_period_id=1)
366+
```
367+
314368
## Build Path4GMNS from Source
315369

316370
If you would like to test the latest features of Path4GMNS or have a compatible version to a specific operating system or an architecture, you can build the package from source and install it offline, where **Python 3.x** is required.
@@ -337,11 +391,11 @@ As **CMAKE_BUILD_TYPE** will be **IGNORED** for IDE (Integrated Development Envi
337391
# from the root directory of PATH4GMNS
338392
$ python setup.py sdist bdist_wheel
339393
$ cd dist
340-
# or python -m pip instal pypath4gmns-0.7.2-py3-none-any.whl
341-
$ python -m pip install path4gmns-0.7.2.tar.gz
394+
# or python -m pip instal pypath4gmns-0.7.3-py3-none-any.whl
395+
$ python -m pip install path4gmns-0.7.3.tar.gz
342396
```
343397

344-
Here, 0.7.2 is the version number. Replace it with the one specified in setup.py.
398+
Here, 0.7.3 is the version number. Replace it with the one specified in setup.py.
345399

346400
## Benchmarks
347401
Coming soon.
@@ -358,6 +412,7 @@ Coming soon.
358412
- [x] Apply lightweight and faster implementation on accessibility evaluation using virtual centroids and connectors (v0.7.0)
359413
- [x] Get accessible nodes and links given mode and time budget (v0.7.0)
360414
- [x] Retrieve shortest paths under multimodal allowed uses (v0.7.2)
415+
- [x] Time-dependent accessibility evaluation (v0.7.3)
361416
- [ ] Let users modify the network topology in a simple way by adding/removing nodes and links
362417
- [ ] Enable manipulations on the overall travel demand and the demand between an OD pair
363418
- [ ] Visualize individual column/paths on user's call
@@ -367,6 +422,6 @@ Coming soon.
367422

368423
The column generation scheme in Path4GMNS is an equivalent **single-processing implementation** as its [DTALite](https://github.com/jdlph/DTALite/tree/main/src_cpp) multiprocessing counterpart. **Note that the results (i.e., column pool and trajectory for an agent) from Path4GMNS and DTALite are comparable but likely not identical as the shortest paths are usually not unique and subjected to implementations**. This subtle difference should be gone and the link performances should be consistent if the iterations on both assignment and column generation are large enough. You can always compare the results (i.e., link_performance.csv) from Path4GMNS and DTALite given the same network and demand.
369424

370-
The whole package is implemented towards **high performance**. The core shortest-path engine is implemented in C++ (deque implementation of the modified label correcting algorithm) along with the equivalent Python implementations for demonstrations. To achieve the maximum efficiency, we use a fixed-length array as the deque (rather than the STL deque) and combine the scan eligible list (represented as deque) with the node presence status. Along with the minimum and fast argument interfacing between the underlying C++ path engine and the upper Python modules, its running time is comparable to the pure C++-based DTALite. If you have an extremely large network and/or have requirement on CPU time, we recommend using DTALite to fully utilze its parallel computing feature.
425+
The whole package is implemented towards **high performance**. The core shortest-path engine is implemented in C++ (deque implementation of the modified label correcting algorithm) along with the equivalent Python implementations for demonstration. To achieve the maximum efficiency, we use a fixed-length array as the deque (rather than the STL deque) and combine the scan eligible list (represented as deque) with the node presence status. Along with the minimum and fast argument interfacing between the underlying C++ path engine and the upper Python modules, its running time is comparable to the pure C++-based DTALite for small- and medium-size networks (e.g., the Chicago Sketch Network). If you have an extremely large network and/or have requirement on CPU time, we recommend using DTALite to fully utilze its parallel computing feature.
371426

372-
An easy and smooth installation process by **low dependency** is one of our major design goals. The core Python modules in Path4GMNS only require a handful of components from the Python standard library (e.g., csv, cytpes, and so on) with no any third-party libraries/packages. On the C++ side, the precompiled path engine as shared libraries are embedded to make this package portable across three major desktop environments (i.e., Windows, macOS, and Linux) and its source is implemented in C++11 with no dependency. Users can easily build the path engine from the source code towards the target system if it is not listed as one of the three.
427+
An easy and smooth installation process by **low dependency** is one of our major design goals. The core Python modules in Path4GMNS only require a handful of components from the Python standard library (e.g., csv, cytpes, and so on) with no any third-party libraries/packages. On the C++ side, the precompiled path engine as shared libraries are embedded to make this package portable across three major desktop environments (i.e., Windows, macOS, and Linux) and its source is implemented in C++11 with no dependency. Users can easily build the path engine from the source code towards their target system if it is not listed above as one of the three.

path4gmns/accessibility.py

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def _output_accessibility(min_travel_times, zones, mode='p', output_dir='.'):
7373
continue
7474

7575
# output assessiblity
76-
# no exception handlings here as min_travel_times is constructed
76+
# no exception handlings here as min_travel_times is constructed
7777
# directly using an.get_centroids()
7878
coord_oz = zones[k[0]]
7979
coord_dz = zones[k[1]]
@@ -142,12 +142,76 @@ def _output_accessibility_aggregated(min_travel_times, interval_num,
142142
+' for aggregated accessibility matrix')
143143

144144

145-
def evaluate_accessibility(ui, multimodal=True, mode='p', time_dependent=False, demand_period_id=0, output_dir='.'):
145+
def evaluate_accessibility(ui,
146+
multimodal=True,
147+
mode='p',
148+
time_dependent=False,
149+
demand_period_id=0,
150+
output_dir='.'):
151+
""" perform accessibility evaluation for a target mode or more
152+
153+
Parameters
154+
----------
155+
ui
156+
network object generated by pg.read_network()
157+
158+
multimodal
159+
True or False. Its default value is True. It will only affect the
160+
output to accessibility_aggregated.csv.
161+
162+
If True, the accessiblity evalution will be conducted
163+
for all the modes defined in settings.yml. The number of accessible
164+
zones from each zone under each defined mode given a budget time (up
165+
to 240 minutes) will be outputted to accessibility_aggregated.csv.
166+
167+
If False, the accessiblity evalution will be only conducted against the
168+
target mode. The number of accessible zones from each zone under the
169+
target mode given a budget time (up to 240 minutes) will be outputted
170+
to accessibility_aggregated.csv.
171+
172+
mode
173+
target mode with its default value as 'p' (i.e., mode auto). It can be
174+
either agent type or its name. For example, 'w' and 'walk' are
175+
equivalent inputs.
176+
177+
time_dependent
178+
True or False. Its default value is False.
179+
180+
If True, the accessibility will be evaluated using the period link
181+
free-flow travel time (i.e., VDF_fftt). In other words, the
182+
accessibility is time-dependent.
183+
184+
If False, the accessibility will be evaluated using the link length and
185+
the free flow travel speed of each mode.
186+
187+
demand_period_id
188+
The sequence number of demand period listed in demand_periods in
189+
settings.yml. demand_period_id of the first demand_period is 0.
190+
191+
Use it with time_dependent when there are multiple demand periods. Its
192+
default value is 0.
193+
194+
output_dir
195+
The directory path where accessibility_aggregated.csv and
196+
accessibility.csv are outputed. The default is the current working
197+
directory (CDW).
198+
199+
200+
Outputs
201+
-------
202+
accessibility_aggregated.csv
203+
aggregated accessibility as the number of accessible zones from each
204+
zone for a target mode or any mode defined in settings.yml given a
205+
budget time (up to 240 minutes).
206+
207+
accessibility.csv:
208+
accessibility between each OD pair in terms of free flow travel time.
209+
"""
146210
base = ui._base_assignment
147211
an = AccessNetwork(base.network)
148212
ats = None
149213

150-
# map zone id to zone centroid coordinate
214+
# map zone id to zone centroid coordinate
151215
zones = {}
152216
for c in an.get_centroids():
153217
zones[c.get_zone_id()] = c.get_coordinate()

0 commit comments

Comments
 (0)