scgraph 3.5.0__tar.gz → 3.6.0b2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- scgraph-3.6.0b2/CMakeLists.txt +48 -0
- {scgraph-3.5.0 → scgraph-3.6.0b2}/PKG-INFO +32 -21
- {scgraph-3.5.0 → scgraph-3.6.0b2}/README.md +32 -21
- {scgraph-3.5.0 → scgraph-3.6.0b2}/pyproject.toml +23 -4
- {scgraph-3.5.0 → scgraph-3.6.0b2}/scgraph/__init__.py +33 -22
- {scgraph-3.5.0 → scgraph-3.6.0b2}/scgraph/contraction_hierarchies.py +51 -30
- {scgraph-3.5.0 → scgraph-3.6.0b2}/scgraph/cpp/bindings/graph_bindings.cpp +46 -38
- {scgraph-3.5.0 → scgraph-3.6.0b2}/scgraph/cpp/src/contraction_hierarchies.cpp +46 -16
- {scgraph-3.5.0 → scgraph-3.6.0b2}/scgraph/cpp/src/contraction_hierarchies.hpp +13 -3
- scgraph-3.6.0b2/scgraph/cpp/src/graph.cpp +1245 -0
- scgraph-3.6.0b2/scgraph/cpp/src/graph.hpp +63 -0
- {scgraph-3.5.0 → scgraph-3.6.0b2}/scgraph/cpp/src/graph_reducer.cpp +22 -19
- {scgraph-3.5.0 → scgraph-3.6.0b2}/scgraph/cpp/src/graph_reducer.hpp +2 -1
- {scgraph-3.5.0 → scgraph-3.6.0b2}/scgraph/cpp/src/graph_utils.cpp +93 -17
- {scgraph-3.5.0 → scgraph-3.6.0b2}/scgraph/cpp/src/graph_utils.hpp +13 -4
- {scgraph-3.5.0 → scgraph-3.6.0b2}/scgraph/cpp/src/transit_node_routing.cpp +123 -75
- {scgraph-3.5.0 → scgraph-3.6.0b2}/scgraph/cpp/src/transit_node_routing.hpp +5 -2
- {scgraph-3.5.0 → scgraph-3.6.0b2}/scgraph/geograph.py +231 -257
- {scgraph-3.5.0 → scgraph-3.6.0b2}/scgraph/graph.py +485 -166
- {scgraph-3.5.0 → scgraph-3.6.0b2}/scgraph/graph_reducer.py +163 -82
- {scgraph-3.5.0 → scgraph-3.6.0b2}/scgraph/graph_utils.py +77 -22
- {scgraph-3.5.0 → scgraph-3.6.0b2}/scgraph/grid.py +43 -9
- {scgraph-3.5.0 → scgraph-3.6.0b2}/scgraph/transit_node_routing.py +74 -38
- scgraph-3.5.0/CMakeLists.txt +0 -92
- scgraph-3.5.0/scgraph/cpp/src/graph.cpp +0 -778
- scgraph-3.5.0/scgraph/cpp/src/graph.hpp +0 -61
- {scgraph-3.5.0 → scgraph-3.6.0b2}/LICENSE +0 -0
- {scgraph-3.5.0 → scgraph-3.6.0b2}/scgraph/cpp/src/bmssp.hpp +0 -0
- {scgraph-3.5.0 → scgraph-3.6.0b2}/scgraph/helpers/__init__.py +0 -0
- {scgraph-3.5.0 → scgraph-3.6.0b2}/scgraph/helpers/geojson.py +0 -0
- {scgraph-3.5.0 → scgraph-3.6.0b2}/scgraph/helpers/visvalingam.py +0 -0
- {scgraph-3.5.0 → scgraph-3.6.0b2}/scgraph/utils.py +0 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
cmake_minimum_required(VERSION 3.15)
|
|
2
|
+
|
|
3
|
+
# -----------------------------
|
|
4
|
+
# Define The Project
|
|
5
|
+
# -----------------------------
|
|
6
|
+
project(scgraph LANGUAGES CXX)
|
|
7
|
+
|
|
8
|
+
# -----------------------------
|
|
9
|
+
# Find Packages
|
|
10
|
+
# -----------------------------
|
|
11
|
+
find_package(Python 3.10 REQUIRED COMPONENTS Interpreter Development.Module)
|
|
12
|
+
find_package(nanobind CONFIG REQUIRED)
|
|
13
|
+
|
|
14
|
+
# -----------------------------
|
|
15
|
+
# Set C++ standard
|
|
16
|
+
# -----------------------------
|
|
17
|
+
set(CMAKE_CXX_STANDARD 20)
|
|
18
|
+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
19
|
+
|
|
20
|
+
# -----------------------------
|
|
21
|
+
# OPTIMIZATION FLAGS
|
|
22
|
+
# -----------------------------
|
|
23
|
+
set(CMAKE_BUILD_TYPE Release)
|
|
24
|
+
if(MSVC)
|
|
25
|
+
set(CMAKE_CXX_FLAGS_RELEASE "/O2 /DNDEBUG")
|
|
26
|
+
else()
|
|
27
|
+
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -fno-math-errno -fomit-frame-pointer")
|
|
28
|
+
endif()
|
|
29
|
+
|
|
30
|
+
# -----------------------------
|
|
31
|
+
# Graph module
|
|
32
|
+
# -----------------------------
|
|
33
|
+
nanobind_add_module(
|
|
34
|
+
cpp
|
|
35
|
+
STABLE_ABI
|
|
36
|
+
scgraph/cpp/bindings/graph_bindings.cpp
|
|
37
|
+
scgraph/cpp/src/graph.cpp
|
|
38
|
+
scgraph/cpp/src/graph_utils.cpp
|
|
39
|
+
scgraph/cpp/src/graph_reducer.cpp
|
|
40
|
+
scgraph/cpp/src/contraction_hierarchies.cpp
|
|
41
|
+
scgraph/cpp/src/transit_node_routing.cpp
|
|
42
|
+
)
|
|
43
|
+
install(TARGETS cpp DESTINATION scgraph)
|
|
44
|
+
|
|
45
|
+
# -----------------------------
|
|
46
|
+
# Install Python package files
|
|
47
|
+
# -----------------------------
|
|
48
|
+
install(DIRECTORY scgraph DESTINATION . FILES_MATCHING PATTERN "*.py")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: scgraph
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.6.0b2
|
|
4
4
|
Summary: Determine an approximate distance and route between two points on earth.
|
|
5
5
|
Author-Email: Connor Makowski <conmak@mit.edu>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -11,7 +11,7 @@ Project-URL: Homepage, https://github.com/connor-makowski/scgraph
|
|
|
11
11
|
Project-URL: Bug Tracker, https://github.com/connor-makowski/scgraph/issues
|
|
12
12
|
Project-URL: Documentation, https://connor-makowski.github.io/scgraph/scgraph.html
|
|
13
13
|
Requires-Python: >=3.11
|
|
14
|
-
Requires-Dist: geokdtree
|
|
14
|
+
Requires-Dist: geokdtree>=1.3.0
|
|
15
15
|
Requires-Dist: bmsspy<3.0.0,>=2.2.1
|
|
16
16
|
Requires-Dist: requests<3.0.0,>=2.32.0
|
|
17
17
|
Provides-Extra: dev
|
|
@@ -68,18 +68,33 @@ If you use SCGraph in your research, please cite:
|
|
|
68
68
|
pip install scgraph
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
### Pure Python Installation (Skip Binary Builds)
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
If you want to install `scgraph` in pure Python mode without compiling or using binary extensions (or in environments without a C++ compiler):
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
```
|
|
75
|
+
- **Linux / macOS / WSL2**:
|
|
76
|
+
```bash
|
|
77
|
+
SCGRAPH_NO_BUILD=1 pip install --no-binary scgraph scgraph
|
|
78
|
+
```
|
|
79
|
+
Or with `uv`:
|
|
80
|
+
```bash
|
|
81
|
+
SCGRAPH_NO_BUILD=1 uv pip install --no-binary scgraph scgraph
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
- **Windows (PowerShell)**:
|
|
85
|
+
```powershell
|
|
86
|
+
$env:SCGRAPH_NO_BUILD="1"
|
|
87
|
+
pip install --no-binary scgraph scgraph
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
- **Windows (CMD)**:
|
|
91
|
+
```cmd
|
|
92
|
+
set SCGRAPH_NO_BUILD=1
|
|
93
|
+
pip install --no-binary scgraph scgraph
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
#### Automatic Fallback
|
|
97
|
+
When building from source, if a C++ compiler is not available or compilation fails, `scgraph` will automatically fall back to a pure Python implementation.
|
|
83
98
|
|
|
84
99
|
---
|
|
85
100
|
|
|
@@ -200,9 +215,10 @@ All algorithms are available on `Graph` objects and accessible from `GeoGraph` v
|
|
|
200
215
|
|
|
201
216
|
| `algorithm_fn` | Description | Time Complexity |
|
|
202
217
|
|---|---|---|
|
|
203
|
-
| `'dijkstra'` | Standard Dijkstra; general purpose, non-negative weights
|
|
218
|
+
| `'dijkstra'` | Standard Dijkstra; general purpose, non-negative weights | O((n+m) log n) |
|
|
204
219
|
| `'bidirectional_dijkstra'` | Bidirectional Dijkstra; simultaneous search from origin and destination | O((n+m) log n) |
|
|
205
220
|
| `'dijkstra_buckets'` | Dijkstra with buckets (Dial's algorithm); efficient for non-negative weights (ideally >= 1) | O(n+m+W) |
|
|
221
|
+
| `'bidirectional_buckets'` | Bidirectional Dijkstra (default for geographs) with buckets (Dial's algorithm); efficient for non-negative weights | O(n+m+W) |
|
|
206
222
|
| `'dijkstra_negative'` | Dijkstra with cycle detection; supports negative weights | O(n·m) |
|
|
207
223
|
| `'a_star'` | A* with optional heuristic; faster than Dijkstra with a good heuristic | O((n+m) log n) |
|
|
208
224
|
| `'bellman_ford'` | Bellman-Ford; supports negative weights, slower than Dijkstra | O(n·m) |
|
|
@@ -215,7 +231,7 @@ All algorithms are available on `Graph` objects and accessible from `GeoGraph` v
|
|
|
215
231
|
|
|
216
232
|
| Scenario | Recommended Approach |
|
|
217
233
|
|---|---|
|
|
218
|
-
| Single query | `dijkstra`
|
|
234
|
+
| Single query | `dijkstra`, `bidirectional_buckets` or `bidirectional_dijkstra` |
|
|
219
235
|
| Sparse networks (road/rail/maritime) | Reduce with `geograph.reduce()` for 2–4x faster queries |
|
|
220
236
|
| Weights generally >= 1 | `dijkstra_buckets` |
|
|
221
237
|
| Repeated queries from one origin | `cached_shortest_path` |
|
|
@@ -410,15 +426,10 @@ output = marnet_geograph.get_shortest_path(
|
|
|
410
426
|
|
|
411
427
|
| `node_addition_type` | Description |
|
|
412
428
|
|---|---|
|
|
413
|
-
| `'kdclosest'` | Closest node via
|
|
414
|
-
| `'
|
|
415
|
-
| `'quadrant'` | Closest node in each of 4 quadrants |
|
|
429
|
+
| `'closest'` / `'kdclosest'` | Closest node via GeoKDTree (default) |
|
|
430
|
+
| `'quadrant'` / `'kdquadrant'` | Closest node in each quadrant via GeoKDTree |
|
|
416
431
|
| `'all'` | All nodes within the bound |
|
|
417
432
|
|
|
418
|
-
| `node_addition_math` | Description |
|
|
419
|
-
|---|---|
|
|
420
|
-
| `'euclidean'` | Fast planar distance (default) |
|
|
421
|
-
| `'haversine'` | Accurate great-circle distance |
|
|
422
433
|
|
|
423
434
|
---
|
|
424
435
|
|
|
@@ -40,18 +40,33 @@ If you use SCGraph in your research, please cite:
|
|
|
40
40
|
pip install scgraph
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
```
|
|
43
|
+
### Pure Python Installation (Skip Binary Builds)
|
|
44
|
+
|
|
45
|
+
If you want to install `scgraph` in pure Python mode without compiling or using binary extensions (or in environments without a C++ compiler):
|
|
46
|
+
|
|
47
|
+
- **Linux / macOS / WSL2**:
|
|
48
|
+
```bash
|
|
49
|
+
SCGRAPH_NO_BUILD=1 pip install --no-binary scgraph scgraph
|
|
50
|
+
```
|
|
51
|
+
Or with `uv`:
|
|
52
|
+
```bash
|
|
53
|
+
SCGRAPH_NO_BUILD=1 uv pip install --no-binary scgraph scgraph
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
- **Windows (PowerShell)**:
|
|
57
|
+
```powershell
|
|
58
|
+
$env:SCGRAPH_NO_BUILD="1"
|
|
59
|
+
pip install --no-binary scgraph scgraph
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
- **Windows (CMD)**:
|
|
63
|
+
```cmd
|
|
64
|
+
set SCGRAPH_NO_BUILD=1
|
|
65
|
+
pip install --no-binary scgraph scgraph
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
#### Automatic Fallback
|
|
69
|
+
When building from source, if a C++ compiler is not available or compilation fails, `scgraph` will automatically fall back to a pure Python implementation.
|
|
55
70
|
|
|
56
71
|
---
|
|
57
72
|
|
|
@@ -172,9 +187,10 @@ All algorithms are available on `Graph` objects and accessible from `GeoGraph` v
|
|
|
172
187
|
|
|
173
188
|
| `algorithm_fn` | Description | Time Complexity |
|
|
174
189
|
|---|---|---|
|
|
175
|
-
| `'dijkstra'` | Standard Dijkstra; general purpose, non-negative weights
|
|
190
|
+
| `'dijkstra'` | Standard Dijkstra; general purpose, non-negative weights | O((n+m) log n) |
|
|
176
191
|
| `'bidirectional_dijkstra'` | Bidirectional Dijkstra; simultaneous search from origin and destination | O((n+m) log n) |
|
|
177
192
|
| `'dijkstra_buckets'` | Dijkstra with buckets (Dial's algorithm); efficient for non-negative weights (ideally >= 1) | O(n+m+W) |
|
|
193
|
+
| `'bidirectional_buckets'` | Bidirectional Dijkstra (default for geographs) with buckets (Dial's algorithm); efficient for non-negative weights | O(n+m+W) |
|
|
178
194
|
| `'dijkstra_negative'` | Dijkstra with cycle detection; supports negative weights | O(n·m) |
|
|
179
195
|
| `'a_star'` | A* with optional heuristic; faster than Dijkstra with a good heuristic | O((n+m) log n) |
|
|
180
196
|
| `'bellman_ford'` | Bellman-Ford; supports negative weights, slower than Dijkstra | O(n·m) |
|
|
@@ -187,7 +203,7 @@ All algorithms are available on `Graph` objects and accessible from `GeoGraph` v
|
|
|
187
203
|
|
|
188
204
|
| Scenario | Recommended Approach |
|
|
189
205
|
|---|---|
|
|
190
|
-
| Single query | `dijkstra`
|
|
206
|
+
| Single query | `dijkstra`, `bidirectional_buckets` or `bidirectional_dijkstra` |
|
|
191
207
|
| Sparse networks (road/rail/maritime) | Reduce with `geograph.reduce()` for 2–4x faster queries |
|
|
192
208
|
| Weights generally >= 1 | `dijkstra_buckets` |
|
|
193
209
|
| Repeated queries from one origin | `cached_shortest_path` |
|
|
@@ -382,15 +398,10 @@ output = marnet_geograph.get_shortest_path(
|
|
|
382
398
|
|
|
383
399
|
| `node_addition_type` | Description |
|
|
384
400
|
|---|---|
|
|
385
|
-
| `'kdclosest'` | Closest node via
|
|
386
|
-
| `'
|
|
387
|
-
| `'quadrant'` | Closest node in each of 4 quadrants |
|
|
401
|
+
| `'closest'` / `'kdclosest'` | Closest node via GeoKDTree (default) |
|
|
402
|
+
| `'quadrant'` / `'kdquadrant'` | Closest node in each quadrant via GeoKDTree |
|
|
388
403
|
| `'all'` | All nodes within the bound |
|
|
389
404
|
|
|
390
|
-
| `node_addition_math` | Description |
|
|
391
|
-
|---|---|
|
|
392
|
-
| `'euclidean'` | Fast planar distance (default) |
|
|
393
|
-
| `'haversine'` | Accurate great-circle distance |
|
|
394
405
|
|
|
395
406
|
---
|
|
396
407
|
|
|
@@ -4,15 +4,20 @@ target-version = ['py312']
|
|
|
4
4
|
exclude = '/.*(migrations|__pycache__|geographs).*/'
|
|
5
5
|
|
|
6
6
|
[build-system]
|
|
7
|
-
requires = ["
|
|
7
|
+
requires = ["scikit-build-core", "nanobind>=3.1.0"]
|
|
8
8
|
build-backend = "scikit_build_core.build"
|
|
9
9
|
|
|
10
10
|
[tool.scikit-build]
|
|
11
11
|
build.verbose = false
|
|
12
12
|
build-dir = "build/{wheel_tag}"
|
|
13
13
|
|
|
14
|
+
[[tool.scikit-build.overrides]]
|
|
15
|
+
if.env.SCGRAPH_NO_BUILD = true
|
|
16
|
+
wheel.cmake = false
|
|
17
|
+
|
|
14
18
|
[[tool.scikit-build.overrides]]
|
|
15
19
|
if.failed = true
|
|
20
|
+
if.not.env.SCGRAPH_REQUIRE_CPP = true
|
|
16
21
|
wheel.cmake = false
|
|
17
22
|
|
|
18
23
|
[tool.scikit-build.sdist]
|
|
@@ -30,7 +35,7 @@ include = [
|
|
|
30
35
|
|
|
31
36
|
[project]
|
|
32
37
|
name = "scgraph"
|
|
33
|
-
version = "3.
|
|
38
|
+
version = "3.6.0b2"
|
|
34
39
|
description = "Determine an approximate distance and route between two points on earth."
|
|
35
40
|
authors = [
|
|
36
41
|
{name="Connor Makowski", email="conmak@mit.edu"}
|
|
@@ -44,7 +49,7 @@ classifiers = [
|
|
|
44
49
|
"Operating System :: OS Independent",
|
|
45
50
|
]
|
|
46
51
|
dependencies = [
|
|
47
|
-
"geokdtree
|
|
52
|
+
"geokdtree>=1.3.0",
|
|
48
53
|
"bmsspy>=2.2.1,<3.0.0",
|
|
49
54
|
"requests>=2.32.0,<3.0.0"
|
|
50
55
|
]
|
|
@@ -65,6 +70,7 @@ dev = [
|
|
|
65
70
|
[tool.pytest.ini_options]
|
|
66
71
|
testpaths = ["test"]
|
|
67
72
|
pythonpath = ["test"]
|
|
73
|
+
python_files = ["*_test.py"]
|
|
68
74
|
|
|
69
75
|
[tool.uv]
|
|
70
76
|
no-build-isolation-package = []
|
|
@@ -72,4 +78,17 @@ no-build-isolation-package = []
|
|
|
72
78
|
[project.urls]
|
|
73
79
|
"Homepage" = "https://github.com/connor-makowski/scgraph"
|
|
74
80
|
"Bug Tracker" = "https://github.com/connor-makowski/scgraph/issues"
|
|
75
|
-
"Documentation" = "https://connor-makowski.github.io/scgraph/scgraph.html"
|
|
81
|
+
"Documentation" = "https://connor-makowski.github.io/scgraph/scgraph.html"
|
|
82
|
+
|
|
83
|
+
[tool.cibuildwheel]
|
|
84
|
+
build = "cp311-* cp312-* cp313-* cp314-*"
|
|
85
|
+
skip = "*-win32 *_i686 pp*"
|
|
86
|
+
test-command = "pytest {project}/test"
|
|
87
|
+
test-requires = ["pytest>=9.0.3"]
|
|
88
|
+
|
|
89
|
+
[tool.cibuildwheel.linux]
|
|
90
|
+
manylinux-x86_64-image = "manylinux_2_28"
|
|
91
|
+
manylinux-aarch64-image = "manylinux_2_28"
|
|
92
|
+
|
|
93
|
+
[tool.cibuildwheel.windows]
|
|
94
|
+
repair-wheel-command = ""
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""
|
|
1
|
+
r"""
|
|
2
2
|
# SCGraph
|
|
3
3
|
[](https://badge.fury.io/py/scgraph)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
@@ -41,18 +41,33 @@ If you use SCGraph in your research, please cite:
|
|
|
41
41
|
pip install scgraph
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
### Pure Python Installation (Skip Binary Builds)
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
If you want to install `scgraph` in pure Python mode without compiling or using binary extensions (or in environments without a C++ compiler):
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
```
|
|
48
|
+
- **Linux / macOS / WSL2**:
|
|
49
|
+
```bash
|
|
50
|
+
SCGRAPH_NO_BUILD=1 pip install --no-binary scgraph scgraph
|
|
51
|
+
```
|
|
52
|
+
Or with `uv`:
|
|
53
|
+
```bash
|
|
54
|
+
SCGRAPH_NO_BUILD=1 uv pip install --no-binary scgraph scgraph
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
- **Windows (PowerShell)**:
|
|
58
|
+
```powershell
|
|
59
|
+
$env:SCGRAPH_NO_BUILD="1"
|
|
60
|
+
pip install --no-binary scgraph scgraph
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
- **Windows (CMD)**:
|
|
64
|
+
```cmd
|
|
65
|
+
set SCGRAPH_NO_BUILD=1
|
|
66
|
+
pip install --no-binary scgraph scgraph
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
#### Automatic Fallback
|
|
70
|
+
When building from source, if a C++ compiler is not available or compilation fails, `scgraph` will automatically fall back to a pure Python implementation.
|
|
56
71
|
|
|
57
72
|
---
|
|
58
73
|
|
|
@@ -173,9 +188,10 @@ All algorithms are available on `Graph` objects and accessible from `GeoGraph` v
|
|
|
173
188
|
|
|
174
189
|
| `algorithm_fn` | Description | Time Complexity |
|
|
175
190
|
|---|---|---|
|
|
176
|
-
| `'dijkstra'` | Standard Dijkstra; general purpose, non-negative weights
|
|
191
|
+
| `'dijkstra'` | Standard Dijkstra; general purpose, non-negative weights | O((n+m) log n) |
|
|
177
192
|
| `'bidirectional_dijkstra'` | Bidirectional Dijkstra; simultaneous search from origin and destination | O((n+m) log n) |
|
|
178
193
|
| `'dijkstra_buckets'` | Dijkstra with buckets (Dial's algorithm); efficient for non-negative weights (ideally >= 1) | O(n+m+W) |
|
|
194
|
+
| `'bidirectional_buckets'` | Bidirectional Dijkstra (default for geographs) with buckets (Dial's algorithm); efficient for non-negative weights | O(n+m+W) |
|
|
179
195
|
| `'dijkstra_negative'` | Dijkstra with cycle detection; supports negative weights | O(n·m) |
|
|
180
196
|
| `'a_star'` | A* with optional heuristic; faster than Dijkstra with a good heuristic | O((n+m) log n) |
|
|
181
197
|
| `'bellman_ford'` | Bellman-Ford; supports negative weights, slower than Dijkstra | O(n·m) |
|
|
@@ -188,7 +204,7 @@ All algorithms are available on `Graph` objects and accessible from `GeoGraph` v
|
|
|
188
204
|
|
|
189
205
|
| Scenario | Recommended Approach |
|
|
190
206
|
|---|---|
|
|
191
|
-
| Single query | `dijkstra`
|
|
207
|
+
| Single query | `dijkstra`, `bidirectional_buckets` or `bidirectional_dijkstra` |
|
|
192
208
|
| Sparse networks (road/rail/maritime) | Reduce with `geograph.reduce()` for 2–4x faster queries |
|
|
193
209
|
| Weights generally >= 1 | `dijkstra_buckets` |
|
|
194
210
|
| Repeated queries from one origin | `cached_shortest_path` |
|
|
@@ -383,15 +399,10 @@ output = marnet_geograph.get_shortest_path(
|
|
|
383
399
|
|
|
384
400
|
| `node_addition_type` | Description |
|
|
385
401
|
|---|---|
|
|
386
|
-
| `'kdclosest'` | Closest node via
|
|
387
|
-
| `'
|
|
388
|
-
| `'quadrant'` | Closest node in each of 4 quadrants |
|
|
402
|
+
| `'closest'` / `'kdclosest'` | Closest node via GeoKDTree (default) |
|
|
403
|
+
| `'quadrant'` / `'kdquadrant'` | Closest node in each quadrant via GeoKDTree |
|
|
389
404
|
| `'all'` | All nodes within the bound |
|
|
390
405
|
|
|
391
|
-
| `node_addition_math` | Description |
|
|
392
|
-
|---|---|
|
|
393
|
-
| `'euclidean'` | Fast planar distance (default) |
|
|
394
|
-
| `'haversine'` | Accurate great-circle distance |
|
|
395
406
|
|
|
396
407
|
---
|
|
397
408
|
|
|
@@ -432,7 +443,7 @@ The cache location defaults to the platform-appropriate directory:
|
|
|
432
443
|
|---|---|
|
|
433
444
|
| Linux | `~/.cache/scgraph/` |
|
|
434
445
|
| macOS | `~/Library/Caches/scgraph/` |
|
|
435
|
-
| Windows | `%LOCALAPPDATA
|
|
446
|
+
| Windows | `%LOCALAPPDATA%\scgraph\` |
|
|
436
447
|
|
|
437
448
|
### `load_geograph` Parameters
|
|
438
449
|
|
|
@@ -817,6 +828,7 @@ Originally inspired by [searoute](https://github.com/genthalili/searoute-py), in
|
|
|
817
828
|
|
|
818
829
|
"""
|
|
819
830
|
|
|
831
|
+
|
|
820
832
|
from scgraph.graph_reducer import algorithm
|
|
821
833
|
|
|
822
834
|
try:
|
|
@@ -829,4 +841,3 @@ except ImportError:
|
|
|
829
841
|
|
|
830
842
|
from scgraph.geograph import GeoGraph
|
|
831
843
|
from scgraph.grid import GridGraph
|
|
832
|
-
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import json
|
|
2
|
-
from heapq import heappush, heappop
|
|
2
|
+
from heapq import heappush, heappop, heapify
|
|
3
3
|
from typing import Callable, Any, Optional, Union
|
|
4
|
-
from scgraph.graph_utils import
|
|
4
|
+
from scgraph.graph_utils import (
|
|
5
|
+
GraphUtils,
|
|
6
|
+
GraphModifiers,
|
|
7
|
+
normalize_node_input,
|
|
8
|
+
)
|
|
5
9
|
|
|
6
10
|
|
|
7
11
|
class CHGraphIO:
|
|
@@ -505,7 +509,10 @@ class CHGraphAlgorithms:
|
|
|
505
509
|
return neighbors
|
|
506
510
|
|
|
507
511
|
def search(
|
|
508
|
-
self,
|
|
512
|
+
self,
|
|
513
|
+
origin_id: int | set[int] | dict[int, int | float],
|
|
514
|
+
destination_id: int | set[int] | dict[int, int | float],
|
|
515
|
+
length_only: bool = False,
|
|
509
516
|
) -> dict[str, Any]:
|
|
510
517
|
"""
|
|
511
518
|
Function:
|
|
@@ -515,11 +522,11 @@ class CHGraphAlgorithms:
|
|
|
515
522
|
Required Arguments:
|
|
516
523
|
|
|
517
524
|
- `origin_id`
|
|
518
|
-
- Type: int
|
|
519
|
-
- What: The id of the origin node
|
|
525
|
+
- Type: int | set[int] | dict[int, int | float]
|
|
526
|
+
- What: The id(s) of the origin node(s) (with optional starting distances)
|
|
520
527
|
- `destination_id`
|
|
521
|
-
- Type: int
|
|
522
|
-
- What: The id of the destination node
|
|
528
|
+
- Type: int | set[int] | dict[int, int | float]
|
|
529
|
+
- What: The id(s) of the destination node(s) (with optional exit distances)
|
|
523
530
|
|
|
524
531
|
Optional Arguments:
|
|
525
532
|
|
|
@@ -531,28 +538,39 @@ class CHGraphAlgorithms:
|
|
|
531
538
|
Returns:
|
|
532
539
|
|
|
533
540
|
- A dictionary with the following keys:
|
|
534
|
-
- `path`: A list of node ids representing the shortest path (
|
|
541
|
+
- `path`: A list of node ids representing the shortest path (empty if length_only=True)
|
|
535
542
|
- `length`: The total length of the shortest path
|
|
536
543
|
"""
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
544
|
+
origin_dict = normalize_node_input(origin_id)
|
|
545
|
+
destination_dict = normalize_node_input(destination_id)
|
|
546
|
+
|
|
547
|
+
overlap = set(origin_dict.keys()) & set(destination_dict.keys())
|
|
548
|
+
best_dist = float("inf")
|
|
549
|
+
meeting_node = -1
|
|
550
|
+
if overlap:
|
|
551
|
+
for node in overlap:
|
|
552
|
+
dist = origin_dict[node] + destination_dict[node]
|
|
553
|
+
if dist < best_dist:
|
|
554
|
+
best_dist = dist
|
|
555
|
+
meeting_node = node
|
|
543
556
|
|
|
544
557
|
# Forward search state
|
|
545
|
-
forward_distances = {
|
|
546
|
-
forward_parent = {
|
|
547
|
-
forward_open_leaves = [
|
|
558
|
+
forward_distances = {node: dist for node, dist in origin_dict.items()}
|
|
559
|
+
forward_parent = {node: -1 for node in origin_dict}
|
|
560
|
+
forward_open_leaves = [
|
|
561
|
+
(dist, node) for node, dist in origin_dict.items()
|
|
562
|
+
]
|
|
563
|
+
heapify(forward_open_leaves)
|
|
548
564
|
|
|
549
565
|
# Backward search state
|
|
550
|
-
backward_distances = {
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
566
|
+
backward_distances = {
|
|
567
|
+
node: dist for node, dist in destination_dict.items()
|
|
568
|
+
}
|
|
569
|
+
backward_parent = {node: -1 for node in destination_dict}
|
|
570
|
+
backward_open_leaves = [
|
|
571
|
+
(dist, node) for node, dist in destination_dict.items()
|
|
572
|
+
]
|
|
573
|
+
heapify(backward_open_leaves)
|
|
556
574
|
|
|
557
575
|
while forward_open_leaves or backward_open_leaves:
|
|
558
576
|
# Forward step
|
|
@@ -688,7 +706,7 @@ class CHGraphAlgorithms:
|
|
|
688
706
|
raise Exception("No path found between origin and destination")
|
|
689
707
|
|
|
690
708
|
if length_only:
|
|
691
|
-
return {"length": best_dist}
|
|
709
|
+
return {"path": [], "length": best_dist}
|
|
692
710
|
|
|
693
711
|
path = self.__reconstruct_ch_path__(
|
|
694
712
|
origin_id,
|
|
@@ -925,7 +943,10 @@ class CHGraph(
|
|
|
925
943
|
return self.original_graph
|
|
926
944
|
|
|
927
945
|
def get_shortest_path(
|
|
928
|
-
self,
|
|
946
|
+
self,
|
|
947
|
+
origin_id: int | set[int] | dict[int, int | float],
|
|
948
|
+
destination_id: int | set[int] | dict[int, int | float],
|
|
949
|
+
**kwargs: Any,
|
|
929
950
|
) -> dict[str, Any]:
|
|
930
951
|
"""
|
|
931
952
|
Function:
|
|
@@ -935,11 +956,11 @@ class CHGraph(
|
|
|
935
956
|
Required Arguments:
|
|
936
957
|
|
|
937
958
|
- `origin_id`
|
|
938
|
-
- Type: int
|
|
939
|
-
- What: The id
|
|
959
|
+
- Type: int | set[int] | dict[int, int | float]
|
|
960
|
+
- What: The origin node id(s), optionally with starting distances
|
|
940
961
|
- `destination_id`
|
|
941
|
-
- Type: int
|
|
942
|
-
- What: The id
|
|
962
|
+
- Type: int | set[int] | dict[int, int | float]
|
|
963
|
+
- What: The destination node id(s), optionally with exit distances
|
|
943
964
|
|
|
944
965
|
Returns:
|
|
945
966
|
|
|
@@ -947,4 +968,4 @@ class CHGraph(
|
|
|
947
968
|
- `path`: A list of node ids representing the shortest path
|
|
948
969
|
- `length`: The total length of the shortest path
|
|
949
970
|
"""
|
|
950
|
-
return self.search(origin_id, destination_id)
|
|
971
|
+
return self.search(origin_id, destination_id, **kwargs)
|