Python bindings for the Customizable Contraction Hierarchies (CCH) implementation from RoutingKit.
Project description
routingkit-cch
Rust/Python bindings for the Customizable Contraction Hierarchies (CCH) implementation from RoutingKit. CCH is a three‑phase shortest path acceleration technique for large directed graphs (e.g. road networks) that allows fast re-weighting while keeping very low query latency.
Why CCH?
CustomizableContractionHierarchies (CCH) are an index-based speedup technique for shortest paths in directed graphs that can quickly be adapted to new weights. CCHs use, contrary to regulars CHs, a three phase setup:
- Preprocessing
- Customization
- Query
The preprocessing is slow but does not rely on the arc weights. The Customization introduces the weights and is reasonably fast. Finally, the actual paths are computed in the query phase. A common setup consists of doing the preprocessing once and the customization per user upon login. Further one can use a customization to incorporate live-traffic updates.
Features
- Safe ergonomic Rust API on top of proven C++ core via
cxx. - Build indices from raw edge lists (tail/head arrays).
- Ordering helpers: nested dissection (inertial separator heuristic) and degree fallback.
- Sequential & parallel customization, and partial weight update afterwards.
- Cheap full re-customization via
CCHMetric::reset(reuses internal buffers). - Reusable query object supporting multi-source / multi-target searches.
- Batched one-to-many / many-to-one queries with pinned targets/sources (
CCHOneToMany,CCHManyToOne). - Path extraction: node sequence & original arc id sequence.
- Thread-safe sharing of immutable structures (
CCH,CCHMetric).
Installation
Rust stable release from crates.io:
[dependencies]
routingkit-cch = "0.1"
Or track the repository:
[dependencies]
routingkit-cch = { git = "https://github.com/HellOwhatAs/routingkit-cch" }
Python stable release from pypi:
pip install routingkit-cch
Or track the repository:
pip install git+https://github.com/HellOwhatAs/routingkit-cch
For the git form ensure the RoutingKit submodule is present:
git submodule update --init --recursive
Requirements: C++17 compiler (MSVC / gcc / clang).
OpenMP is enabled automatically by the build script; ensure your toolchain provides an OpenMP runtime (e.g. install libomp on macOS).
Without it the build may fail when CCHMetric::parallel_new is called.
Quick Start
For python examples, see
examplesfolder.
use routingkit_cch::{CCH, CCHMetric, CCHQuery, compute_order_degree};
// Small toy graph: 0 -> 1 -> 2 -> 3
let tail = vec![0, 1, 2];
let head = vec![1, 2, 3];
let weights = vec![10, 5, 7]; // total 22 from 0 to 3
let node_count = 4u32;
// 1) Compute a (cheap) order; for real data prefer compute_order_inertial (requires lat,lon).
let order = compute_order_degree(node_count, &tail, &head);
let cch = CCH::new(&order, &tail, &head, |_| {}, false);
// 2) Bind weights & customize (done inside CCHMetric::new here).
let metric = CCHMetric::new(&cch, weights.clone());
// 3) Run a shortest path query 0 -> 3.
let mut q = CCHQuery::new(&metric);
q.add_source(0, 0);
q.add_target(3, 0);
let res = q.run();
assert_eq!(res.distance(), Some(22));
let node_path = res.node_path();
assert_eq!(node_path, vec![0, 1, 2, 3]);
let arc_path = res.arc_path();
assert_eq!(arc_path, vec![0, 1, 2]);
Building an Order
For production use prefer the inertial nested dissection based order:
use routingkit_cch::compute_order_inertial;
let order = compute_order_inertial(node_count, &tail, &head, &latitude, &longitude);
Better separators -> faster customization & queries. External advanced orderers (e.g. FlowCutter) could be integrated offline; you only need to supply the permutation.
(Parallel) Customization
use routingkit_cch::{CCH, CCHMetric};
let metric = CCHMetric::new(&cch, weights.clone()); // single thread
let metric = CCHMetric::parallel_new(&cch, weights.clone(), 0); // 0 -> auto threads
Use when graphs are large enough; for tiny graphs overhead may outweigh benefit.
Full Re-Customization (Metric Reset)
When all (or most) weights change (e.g. periodic traffic refresh), rebind the existing metric instead of building a new one; internal shortcut-weight buffers are reused:
let mut metric = CCHMetric::new(&cch, weights);
// ... later, new weights for the same CCH ...
metric.reset(new_weights); // re-customizes in place
// or, with the `openmp` feature:
metric.parallel_reset(new_weights, 0); // 0 -> auto threads
Requires exclusive access: drop all queries borrowing the metric first (enforced by the borrow checker).
Incremental (Partial) Weight Updates
If only a small subset of arc weights change (e.g. traffic incidents), you can avoid a full re-customization:
let mut metric = CCHMetric::parallel_new(&cch, weights.clone(), 0);
let mut updater = CCHMetricPartialUpdater::new(&cch);
// ... run queries ...
// Update two arcs (id 12 -> 900, id 77 -> 450)
updater.apply(&mut metric, &BTreeMap::from_iter([(12, 900), (77, 450)]));
// New queries now see updated weights.
Query
let mut q = CCHQuery::new(&metric);
q.add_source(0, 0);
q.add_target(3, 0);
{
let res = q.run();
printf("{:?}", res.distance());
} // drop res before reusing q since res takes &mut q
q.add_source(2, 0);
q.add_target(5, 0);
{
let res = q.run();
// ...
}
CCHQuery is not thread-safe; create one instance per thread and reuse it is far cheaper than constructing a new one.
One-to-Many / Many-to-One (Batched) Queries
When you need distances from one node to many fixed destinations (distance tables, matrices, k-nearest), pin the destination set once and query it in a single sweep — much faster than a point-to-point query per destination:
use routingkit_cch::{CCHOneToMany, CCHManyToOne};
let mut otm = CCHOneToMany::new(&metric, &targets); // pin once (moderately expensive)
for s in sources {
let dist: Vec<Option<u32>> = otm.distances_from(s); // aligned with `targets`; None = unreachable
}
// Mirror image: distances from many fixed sources to a target.
let mut mto = CCHManyToOne::new(&metric, &sources);
let dist = mto.distances_to(target); // aligned with `sources`
Multi-source/-target variants with initial distance offsets are available
(distances_from_multi, distances_to_multi). Note: batched queries return distances only
(no path reconstruction), matching the underlying RoutingKit API.
Path Reconstruction
After run() -> CCHQueryResult:
CCHQueryResult::distance()->Option<u32>(None = unreachable)CCHQueryResult::node_path()->Vec<node_id>(empty = unreachable)CCHQueryResult::arc_path()->Vec<original_arc_id>(empty = unreachable)
Thread Safety
| Type | Send | Sync | Notes |
|---|---|---|---|
CCH |
yes | yes | Immutable after build |
CCHMetric |
yes | yes | Read-only after customization / partial-update |
CCHQuery |
yes | no | Internal mutable labels; reuse it within thread |
CCHQueryResult |
yes | no | Runned state of CCHQuery, actually &mut of it |
CCHOneToMany |
yes | no | Internal mutable labels; reuse it within thread |
CCHManyToOne |
yes | no | Internal mutable labels; reuse it within thread |
CCHMetricPartialUpdater |
no | no | Should have nothing to do with parallel |
Create separate queries per thread for parallel batch querying.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file routingkit_cch-0.1.4.tar.gz.
File metadata
- Download URL: routingkit_cch-0.1.4.tar.gz
- Upload date:
- Size: 185.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
32fcf13cd645884fb05f13508c33336218d78e832db2affe8671d0ac2874cc52
|
|
| MD5 |
70c2a159b2592e27052f183cebae2949
|
|
| BLAKE2b-256 |
3dd334e30b48d62b273a2a01a1727eff7456b75ab9456dac3a5fbd746360ceeb
|
File details
Details for the file routingkit_cch-0.1.4-cp39-abi3-win_amd64.whl.
File metadata
- Download URL: routingkit_cch-0.1.4-cp39-abi3-win_amd64.whl
- Upload date:
- Size: 233.6 kB
- Tags: CPython 3.9+, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b76918129b99bf5e7ec805dabd2199f8faa5c6e9544bba89a3779b66f748a7bf
|
|
| MD5 |
c776621991df9dc1a3dee862ba4131bf
|
|
| BLAKE2b-256 |
8800aa1151951038f93bddb7dc0bca5a2876709e1423d8a3309fc950272a1234
|
File details
Details for the file routingkit_cch-0.1.4-cp39-abi3-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: routingkit_cch-0.1.4-cp39-abi3-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 7.1 MB
- Tags: CPython 3.9+, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
efa6673a0fda1059cb67e5fc7ed2772c371cb3d9dfac3cb4b7e75289dc3c988d
|
|
| MD5 |
d9da5088bcee2c0dc0ddd3aa2d39a77b
|
|
| BLAKE2b-256 |
81046182eef4302d8f09c3369a432d2d4bf069dd2b088c87e20369de60e6bd26
|
File details
Details for the file routingkit_cch-0.1.4-cp39-abi3-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: routingkit_cch-0.1.4-cp39-abi3-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 6.8 MB
- Tags: CPython 3.9+, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2c9859317da14b0d36175a06dddaaeaa262debca6e120a0e57d420c986fc978c
|
|
| MD5 |
668e2f41c8888929ef8117e8394e1def
|
|
| BLAKE2b-256 |
74548c4566810b89dd6919efab387d18c8697a2274fd1ebcb23fe89b40fc22fa
|
File details
Details for the file routingkit_cch-0.1.4-cp39-abi3-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: routingkit_cch-0.1.4-cp39-abi3-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 417.6 kB
- Tags: CPython 3.9+, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f78f3e5c089ccd30715833c396f23d3607f8f5790180ae9769525e7de1274e40
|
|
| MD5 |
62e4b67f2591320975c86cefe8de73db
|
|
| BLAKE2b-256 |
28e3b2e6c41f3e5b2fff150734ddc61dfb9ce74573a4955dbe07c6fb8439ee0d
|
File details
Details for the file routingkit_cch-0.1.4-cp39-abi3-manylinux_2_34_aarch64.whl.
File metadata
- Download URL: routingkit_cch-0.1.4-cp39-abi3-manylinux_2_34_aarch64.whl
- Upload date:
- Size: 403.6 kB
- Tags: CPython 3.9+, manylinux: glibc 2.34+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c2f91fdd3d11d5b891eb5a3f6d52686223d7a4c97222f7ed916ed63789b36e75
|
|
| MD5 |
f42fa206209de7d8916dc44b938d729f
|
|
| BLAKE2b-256 |
878188beb276c796a884eef9157ddef8910ab45be8adce2cc3a101c0ce250842
|
File details
Details for the file routingkit_cch-0.1.4-cp39-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: routingkit_cch-0.1.4-cp39-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 347.6 kB
- Tags: CPython 3.9+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a0ffeed0458046ec241b2de0035d25034cb09d5df5064ce5092c594be2b105a1
|
|
| MD5 |
4530edcd589125285b7dee73c2d847df
|
|
| BLAKE2b-256 |
b4f1449c6eb137d7cd03e6f8412b69ab1f4503e436a739c6002f69bea7c6bcb6
|
File details
Details for the file routingkit_cch-0.1.4-cp39-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: routingkit_cch-0.1.4-cp39-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 359.8 kB
- Tags: CPython 3.9+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7bc4a6d92f33d700d56139f0fa1148489ef376e3ecfe6010158ed03df8f29161
|
|
| MD5 |
5b7525910eb1193e663bc9d9ac61809f
|
|
| BLAKE2b-256 |
7d7d4a0a6da127cb8a2aa395ba4a6c061e40d860aeeb2098a7bcf7d206562e75
|