edsger 0.1.0__tar.gz → 0.1.2__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.
Files changed (68) hide show
  1. {edsger-0.1.0 → edsger-0.1.2}/.github/workflows/publish.yml +4 -2
  2. edsger-0.1.2/.github/workflows/tests.yml +41 -0
  3. edsger-0.1.2/.pre-commit-config.yaml +14 -0
  4. edsger-0.1.2/PKG-INFO +118 -0
  5. edsger-0.1.2/README.md +77 -0
  6. {edsger-0.1.0 → edsger-0.1.2}/docs/source/api.md +0 -20
  7. edsger-0.1.2/docs/source/assets/dijkstra_benchmark_comparison.png +0 -0
  8. {edsger-0.1.0 → edsger-0.1.2}/docs/source/conf.py +5 -4
  9. edsger-0.1.2/docs/source/index.md +80 -0
  10. {edsger-0.1.0 → edsger-0.1.2}/docs/source/quickstart.md +61 -31
  11. {edsger-0.1.0 → edsger-0.1.2}/pyproject.toml +11 -2
  12. {edsger-0.1.0 → edsger-0.1.2}/requirements-dev.txt +3 -0
  13. edsger-0.1.2/scripts/benchmark_comparison.py +442 -0
  14. {edsger-0.1.0 → edsger-0.1.2}/scripts/dijkstra_dimacs.py +4 -4
  15. edsger-0.1.2/scripts/requirements.txt +11 -0
  16. {edsger-0.1.0 → edsger-0.1.2}/setup.py +9 -3
  17. edsger-0.1.2/src/edsger/.gitignore +1 -0
  18. edsger-0.1.2/src/edsger/_version.py +1 -0
  19. {edsger-0.1.0 → edsger-0.1.2}/src/edsger/commons.c +156 -152
  20. {edsger-0.1.0 → edsger-0.1.2}/src/edsger/commons.pxd +6 -6
  21. {edsger-0.1.0 → edsger-0.1.2}/src/edsger/commons.pyx +4 -4
  22. {edsger-0.1.0 → edsger-0.1.2}/src/edsger/dijkstra.c +1188 -1115
  23. {edsger-0.1.0 → edsger-0.1.2}/src/edsger/dijkstra.pyx +94 -71
  24. {edsger-0.1.0 → edsger-0.1.2}/src/edsger/networks.py +1 -2
  25. {edsger-0.1.0 → edsger-0.1.2}/src/edsger/path.py +1 -1
  26. {edsger-0.1.0 → edsger-0.1.2}/src/edsger/path_tracking.c +152 -148
  27. {edsger-0.1.0 → edsger-0.1.2}/src/edsger/path_tracking.pyx +9 -9
  28. {edsger-0.1.0 → edsger-0.1.2}/src/edsger/pq_4ary_dec_0b.c +299 -295
  29. {edsger-0.1.0 → edsger-0.1.2}/src/edsger/pq_4ary_dec_0b.pxd +7 -7
  30. {edsger-0.1.0 → edsger-0.1.2}/src/edsger/pq_4ary_dec_0b.pyx +74 -76
  31. edsger-0.1.2/src/edsger/prefetch_compat.h +21 -0
  32. {edsger-0.1.0 → edsger-0.1.2}/src/edsger/spiess_florian.c +231 -250
  33. {edsger-0.1.0 → edsger-0.1.2}/src/edsger/spiess_florian.pyx +24 -24
  34. {edsger-0.1.0 → edsger-0.1.2}/src/edsger/star.c +194 -190
  35. {edsger-0.1.0 → edsger-0.1.2}/src/edsger/star.pyx +41 -41
  36. {edsger-0.1.0 → edsger-0.1.2}/src/edsger/utils.py +2 -2
  37. edsger-0.1.2/src/edsger.egg-info/PKG-INFO +118 -0
  38. {edsger-0.1.0 → edsger-0.1.2}/src/edsger.egg-info/SOURCES.txt +6 -0
  39. {edsger-0.1.0 → edsger-0.1.2}/tests/test_dijkstra.py +7 -3
  40. {edsger-0.1.0 → edsger-0.1.2}/tests/test_path.py +1 -1
  41. {edsger-0.1.0 → edsger-0.1.2}/tests/test_path_tracking.py +1 -1
  42. {edsger-0.1.0 → edsger-0.1.2}/tests/test_pq_4ary_dec_0b.py +1 -1
  43. {edsger-0.1.0 → edsger-0.1.2}/tests/test_spiess_florian.py +1 -2
  44. edsger-0.1.0/.github/workflows/tests.yml +0 -28
  45. edsger-0.1.0/PKG-INFO +0 -279
  46. edsger-0.1.0/README.md +0 -243
  47. edsger-0.1.0/docs/source/index.md +0 -54
  48. edsger-0.1.0/src/edsger/_version.py +0 -1
  49. edsger-0.1.0/src/edsger.egg-info/PKG-INFO +0 -279
  50. {edsger-0.1.0 → edsger-0.1.2}/.github/workflows/docs.yml +0 -0
  51. {edsger-0.1.0 → edsger-0.1.2}/.gitignore +0 -0
  52. {edsger-0.1.0 → edsger-0.1.2}/.readthedocs.yaml +0 -0
  53. {edsger-0.1.0 → edsger-0.1.2}/AUTHORS.rst +0 -0
  54. {edsger-0.1.0 → edsger-0.1.2}/CHANGELOG.rst +0 -0
  55. {edsger-0.1.0 → edsger-0.1.2}/CONTRIBUTING.rst +0 -0
  56. {edsger-0.1.0 → edsger-0.1.2}/LICENSE +0 -0
  57. {edsger-0.1.0 → edsger-0.1.2}/MANIFEST.in +0 -0
  58. {edsger-0.1.0 → edsger-0.1.2}/docs/Makefile +0 -0
  59. {edsger-0.1.0 → edsger-0.1.2}/docs/requirements.txt +0 -0
  60. {edsger-0.1.0 → edsger-0.1.2}/docs/source/contributing.md +0 -0
  61. {edsger-0.1.0 → edsger-0.1.2}/docs/source/installation.md +0 -0
  62. {edsger-0.1.0 → edsger-0.1.2}/requirements.txt +0 -0
  63. {edsger-0.1.0 → edsger-0.1.2}/setup.cfg +0 -0
  64. {edsger-0.1.0 → edsger-0.1.2}/src/edsger/__init__.py +0 -0
  65. {edsger-0.1.0 → edsger-0.1.2}/src/edsger.egg-info/dependency_links.txt +0 -0
  66. {edsger-0.1.0 → edsger-0.1.2}/src/edsger.egg-info/not-zip-safe +0 -0
  67. {edsger-0.1.0 → edsger-0.1.2}/src/edsger.egg-info/requires.txt +0 -0
  68. {edsger-0.1.0 → edsger-0.1.2}/src/edsger.egg-info/top_level.txt +0 -0
@@ -10,7 +10,7 @@ jobs:
10
10
  strategy:
11
11
  matrix:
12
12
  os: [ubuntu-latest, windows-latest, macos-latest]
13
- python-version: ["3.11"]
13
+ python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
14
14
  runs-on: ${{ matrix.os }}
15
15
  steps:
16
16
  - uses: actions/checkout@v4
@@ -54,6 +54,7 @@ jobs:
54
54
 
55
55
  - uses: actions/upload-artifact@v4
56
56
  with:
57
+ name: cibw-sdist
57
58
  path: ./dist/*.tar.gz
58
59
 
59
60
  build_wheels:
@@ -95,7 +96,8 @@ jobs:
95
96
  - name: Download all the dists
96
97
  uses: actions/download-artifact@v4
97
98
  with:
98
- name: artifact
99
+ pattern: cibw-*
99
100
  path: ./dist/
101
+ merge-multiple: true
100
102
  - name: Publish distribution to PyPI
101
103
  uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,41 @@
1
+ name: ci-test
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - release
7
+
8
+ jobs:
9
+ test:
10
+ strategy:
11
+ matrix:
12
+ os: [ubuntu-22.04, windows-2022, macos-14]
13
+ python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
14
+ runs-on: ${{ matrix.os }}
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - name: Set up Python ${{ matrix.python-version }}
18
+ uses: actions/setup-python@v5
19
+ with:
20
+ python-version: ${{ matrix.python-version }}
21
+ - name: Install dependencies
22
+ run: |
23
+ python -m pip install --upgrade pip
24
+ pip install -r requirements-dev.txt
25
+ pip install .
26
+ - name: Format Python code with black
27
+ run: |
28
+ black --check --diff .
29
+ - name: Lint Cython code
30
+ run: |
31
+ cython-lint src/edsger/commons.pyx src/edsger/dijkstra.pyx src/edsger/path_tracking.pyx src/edsger/pq_4ary_dec_0b.pyx src/edsger/spiess_florian.pyx src/edsger/star.pyx src/edsger/commons.pxd src/edsger/pq_4ary_dec_0b.pxd
32
+ - name: Testing
33
+ run: |
34
+ python -m pytest --cov=src/edsger --cov-report=xml tests/
35
+ - name: Upload coverage to Codecov
36
+ uses: codecov/codecov-action@v4
37
+ with:
38
+ file: ./coverage.xml
39
+ flags: unittests
40
+ name: codecov-umbrella
41
+ fail_ci_if_error: false
@@ -0,0 +1,14 @@
1
+ repos:
2
+ - repo: https://github.com/psf/black
3
+ rev: 24.10.0
4
+ hooks:
5
+ - id: black
6
+ files: '\.(py)$'
7
+ exclude: 'src/edsger/.*\.pyx$'
8
+
9
+ - repo: https://github.com/MarcoGorelli/cython-lint
10
+ rev: v0.16.2
11
+ hooks:
12
+ - id: cython-lint
13
+ files: '\.(pyx|pxd)$'
14
+ args: [--max-line-length=88]
edsger-0.1.2/PKG-INFO ADDED
@@ -0,0 +1,118 @@
1
+ Metadata-Version: 2.4
2
+ Name: edsger
3
+ Version: 0.1.2
4
+ Summary: Graph algorithms in Cython.
5
+ Author-email: François Pacull <francois.pacull@architecture-performance.fr>
6
+ Maintainer-email: François Pacull <francois.pacull@architecture-performance.fr>
7
+ License: MIT License
8
+ Project-URL: Repository, https://github.com/aetperf/Edsger
9
+ Project-URL: Documentation, https://edsger.readthedocs.io
10
+ Keywords: python,graph,shortest path,Dijkstra
11
+ Platform: any
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: License :: OSI Approved :: MIT License
20
+ Classifier: Operating System :: OS Independent
21
+ Classifier: Topic :: Scientific/Engineering
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ License-File: AUTHORS.rst
26
+ Requires-Dist: setuptools
27
+ Requires-Dist: setuptools_scm
28
+ Requires-Dist: numpy>=1.26
29
+ Requires-Dist: Cython>=3
30
+ Requires-Dist: pandas
31
+ Provides-Extra: dev
32
+ Requires-Dist: black; extra == "dev"
33
+ Provides-Extra: test
34
+ Requires-Dist: pytest; extra == "test"
35
+ Requires-Dist: scipy<1.11; extra == "test"
36
+ Provides-Extra: doc
37
+ Requires-Dist: sphinx; extra == "doc"
38
+ Requires-Dist: sphinx_design; extra == "doc"
39
+ Requires-Dist: sphinx_rtd_theme; extra == "doc"
40
+ Dynamic: license-file
41
+
42
+
43
+ ![Tests Status](https://github.com/aetperf/edsger/actions/workflows/tests.yml/badge.svg?branch=release)
44
+ [![codecov](https://codecov.io/gh/aetperf/edsger/branch/release/graph/badge.svg)](https://codecov.io/gh/aetperf/edsger)
45
+ [![PyPI version](https://img.shields.io/pypi/v/edsger.svg)](https://pypi.org/project/edsger/)
46
+ [![Downloads](https://static.pepy.tech/badge/edsger)](https://pepy.tech/project/edsger)
47
+ [![Python 3.9 | 3.10 | 3.11 | 3.12 | 3.13](https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue)](https://pypi.org/project/edsger/)
48
+ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
49
+ [![Cython lint: cython-lint](https://img.shields.io/badge/cython--lint-enabled-brightgreen.svg)](https://github.com/MarcoGorelli/cython-lint)
50
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
51
+
52
+ # Edsger
53
+
54
+ *Graph algorithms in Cython*
55
+
56
+ Welcome to our Python library for graph algorithms. So far, the library only includes Dijkstra's algorithm but we should add a range of common path algorithms later. It is also open-source and easy to integrate with other Python libraries. To get started, simply install the library using pip, and import it into your Python project.
57
+
58
+ Documentation : [https://edsger.readthedocs.io/en/latest/](https://edsger.readthedocs.io/en/latest/)
59
+
60
+ ## Small example : Dijkstra's Algorithm
61
+
62
+ To use Dijkstra's algorithm, you can import the `Dijkstra` class from the `path` module. The function takes a graph and a source node as input, and returns the shortest path from the source node to all other nodes in the graph.
63
+
64
+ ```python
65
+ import pandas as pd
66
+
67
+ from edsger.path import Dijkstra
68
+
69
+ # Create a DataFrame with the edges of the graph
70
+ edges = pd.DataFrame({
71
+ 'tail': [0, 0, 1, 2, 2, 3],
72
+ 'head': [1, 2, 2, 3, 4, 4],
73
+ 'weight': [1, 4, 2, 1.5, 3, 1]
74
+ })
75
+ edges
76
+ ```
77
+
78
+ | | tail | head | weight |
79
+ |---:|-------:|-------:|---------:|
80
+ | 0 | 0 | 1 | 1.0 |
81
+ | 1 | 0 | 2 | 4.0 |
82
+ | 2 | 1 | 2 | 2.0 |
83
+ | 3 | 2 | 3 | 1.5 |
84
+ | 4 | 2 | 4 | 3.0 |
85
+ | 5 | 3 | 4 | 1.0 |
86
+
87
+ ```python
88
+ # Initialize the Dijkstra object
89
+ dijkstra = Dijkstra(edges)
90
+
91
+ # Run the algorithm from a source vertex
92
+ shortest_paths = dijkstra.run(vertex_idx=0)
93
+ print("Shortest paths:", shortest_paths)
94
+ ```
95
+
96
+ Shortest paths: [0. 1. 3. 4.5 5.5]
97
+
98
+ We get the shortest paths from the source node 0 to all other nodes in the graph. The output is an array with the shortest path length to each node. A path length is the sum of the weights of the edges in the path.
99
+
100
+ ## Why Use Edsger?
101
+
102
+ Edsger is designed to be **dataframe-friendly**, providing seamless integration with pandas workflows for graph algorithms. Also it is rather efficient. Our benchmarks on the USA road network (23.9M vertices, 57.7M edges) demonstrate nice performance:
103
+
104
+ <img src="docs/source/assets/dijkstra_benchmark_comparison.png" alt="Dijkstra Performance Comparison" width="700">
105
+
106
+ *Benchmark performed on Intel i9-12900H laptop.*
107
+
108
+ ## Contributing
109
+
110
+ We welcome contributions to the Edsger library. If you have any suggestions, bug reports, or feature requests, please open an issue on our [GitHub repository](https://github.com/aetperf/Edsger).
111
+
112
+ ## License
113
+
114
+ Edsger is licensed under the MIT License. See the LICENSE file for more details.
115
+
116
+ ## Contact
117
+
118
+ For any questions or inquiries, please contact François Pacull at [francois.pacull@architecture-performance.fr](mailto:francois.pacull@architecture-performance.fr).
edsger-0.1.2/README.md ADDED
@@ -0,0 +1,77 @@
1
+
2
+ ![Tests Status](https://github.com/aetperf/edsger/actions/workflows/tests.yml/badge.svg?branch=release)
3
+ [![codecov](https://codecov.io/gh/aetperf/edsger/branch/release/graph/badge.svg)](https://codecov.io/gh/aetperf/edsger)
4
+ [![PyPI version](https://img.shields.io/pypi/v/edsger.svg)](https://pypi.org/project/edsger/)
5
+ [![Downloads](https://static.pepy.tech/badge/edsger)](https://pepy.tech/project/edsger)
6
+ [![Python 3.9 | 3.10 | 3.11 | 3.12 | 3.13](https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue)](https://pypi.org/project/edsger/)
7
+ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
8
+ [![Cython lint: cython-lint](https://img.shields.io/badge/cython--lint-enabled-brightgreen.svg)](https://github.com/MarcoGorelli/cython-lint)
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
10
+
11
+ # Edsger
12
+
13
+ *Graph algorithms in Cython*
14
+
15
+ Welcome to our Python library for graph algorithms. So far, the library only includes Dijkstra's algorithm but we should add a range of common path algorithms later. It is also open-source and easy to integrate with other Python libraries. To get started, simply install the library using pip, and import it into your Python project.
16
+
17
+ Documentation : [https://edsger.readthedocs.io/en/latest/](https://edsger.readthedocs.io/en/latest/)
18
+
19
+ ## Small example : Dijkstra's Algorithm
20
+
21
+ To use Dijkstra's algorithm, you can import the `Dijkstra` class from the `path` module. The function takes a graph and a source node as input, and returns the shortest path from the source node to all other nodes in the graph.
22
+
23
+ ```python
24
+ import pandas as pd
25
+
26
+ from edsger.path import Dijkstra
27
+
28
+ # Create a DataFrame with the edges of the graph
29
+ edges = pd.DataFrame({
30
+ 'tail': [0, 0, 1, 2, 2, 3],
31
+ 'head': [1, 2, 2, 3, 4, 4],
32
+ 'weight': [1, 4, 2, 1.5, 3, 1]
33
+ })
34
+ edges
35
+ ```
36
+
37
+ | | tail | head | weight |
38
+ |---:|-------:|-------:|---------:|
39
+ | 0 | 0 | 1 | 1.0 |
40
+ | 1 | 0 | 2 | 4.0 |
41
+ | 2 | 1 | 2 | 2.0 |
42
+ | 3 | 2 | 3 | 1.5 |
43
+ | 4 | 2 | 4 | 3.0 |
44
+ | 5 | 3 | 4 | 1.0 |
45
+
46
+ ```python
47
+ # Initialize the Dijkstra object
48
+ dijkstra = Dijkstra(edges)
49
+
50
+ # Run the algorithm from a source vertex
51
+ shortest_paths = dijkstra.run(vertex_idx=0)
52
+ print("Shortest paths:", shortest_paths)
53
+ ```
54
+
55
+ Shortest paths: [0. 1. 3. 4.5 5.5]
56
+
57
+ We get the shortest paths from the source node 0 to all other nodes in the graph. The output is an array with the shortest path length to each node. A path length is the sum of the weights of the edges in the path.
58
+
59
+ ## Why Use Edsger?
60
+
61
+ Edsger is designed to be **dataframe-friendly**, providing seamless integration with pandas workflows for graph algorithms. Also it is rather efficient. Our benchmarks on the USA road network (23.9M vertices, 57.7M edges) demonstrate nice performance:
62
+
63
+ <img src="docs/source/assets/dijkstra_benchmark_comparison.png" alt="Dijkstra Performance Comparison" width="700">
64
+
65
+ *Benchmark performed on Intel i9-12900H laptop.*
66
+
67
+ ## Contributing
68
+
69
+ We welcome contributions to the Edsger library. If you have any suggestions, bug reports, or feature requests, please open an issue on our [GitHub repository](https://github.com/aetperf/Edsger).
70
+
71
+ ## License
72
+
73
+ Edsger is licensed under the MIT License. See the LICENSE file for more details.
74
+
75
+ ## Contact
76
+
77
+ For any questions or inquiries, please contact François Pacull at [francois.pacull@architecture-performance.fr](mailto:francois.pacull@architecture-performance.fr).
@@ -114,23 +114,3 @@ paths = dijkstra.run(
114
114
  heap_length_ratio=0.5
115
115
  )
116
116
  ```
117
-
118
- ### Graph Data Format
119
-
120
- Edsger expects graph data as a pandas DataFrame with the following structure:
121
-
122
- | Column | Type | Description |
123
- |--------|---------|--------------------------------------|
124
- | tail | int | Source vertex ID |
125
- | head | int | Destination vertex ID |
126
- | weight | float | Edge weight (must be non-negative) |
127
-
128
- Example:
129
- ```python
130
- edges = pd.DataFrame({
131
- 'tail': [0, 0, 1, 2],
132
- 'head': [1, 2, 2, 3],
133
- 'weight': [1.0, 4.0, 2.0, 1.0]
134
- })
135
- ```
136
-
@@ -18,12 +18,13 @@ sys.path.insert(0, os.path.abspath("../../src/"))
18
18
  # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
19
19
 
20
20
  project = "Edsger"
21
- copyright = "2024, Architecture & Performance"
21
+ copyright = "2025, Architecture & Performance"
22
22
  author = "Francois Pacull"
23
23
 
24
24
  # Get version from the package
25
25
  try:
26
26
  from edsger._version import __version__
27
+
27
28
  release = __version__
28
29
  version = __version__
29
30
  except ImportError:
@@ -69,6 +70,6 @@ myst_enable_extensions = [
69
70
 
70
71
  # Source suffix
71
72
  source_suffix = {
72
- '.rst': 'restructuredtext',
73
- '.md': 'markdown',
74
- }
73
+ ".rst": "restructuredtext",
74
+ ".md": "markdown",
75
+ }
@@ -0,0 +1,80 @@
1
+ ---
2
+ github_url: https://github.com/aetperf/Edsger
3
+ ---
4
+
5
+ # Edsger
6
+
7
+ *Graph algorithms in Cython*
8
+
9
+ Welcome to the Edsger documentation! Edsger is a Python library for efficient graph algorithms implemented in Cython. The library currently focuses on shortest path algorithms, with Dijkstra's algorithm fully implemented and additional algorithms planned for future releases.
10
+
11
+ ## Why Use Edsger?
12
+
13
+ Edsger is designed to be **dataframe-friendly**, providing seamless integration with pandas workflows for graph algorithms. Also it is rather efficient. Our benchmarks on the USA road network (23.9M vertices, 57.7M edges) demonstrate nice performance:
14
+
15
+ <img src="assets/dijkstra_benchmark_comparison.png" alt="Dijkstra Performance Comparison" width="700">
16
+
17
+ *Benchmark performed on Intel i9-12900H laptop.*
18
+
19
+ ### Pandas Integration Made Simple
20
+
21
+ ```python
22
+ import pandas as pd
23
+ from edsger.path import Dijkstra
24
+
25
+ # Your graph data is already in a DataFrame
26
+ edges = pd.DataFrame({
27
+ 'tail': [0, 0, 1, 2],
28
+ 'head': [1, 2, 2, 3],
29
+ 'weight': [1.0, 2.0, 1.5, 1.0]
30
+ })
31
+
32
+ # No conversion needed - use directly!
33
+ dijkstra = Dijkstra(edges, orientation="out")
34
+ distances = dijkstra.run(vertex_idx=0)
35
+ ```
36
+
37
+ ## Key Features
38
+
39
+ - **Native pandas DataFrame support** - No graph object conversion required
40
+ - **High performance** - Cython implementation with aggressive optimizations
41
+ - **Memory efficient** - Optimized for large-scale real-world datasets
42
+ - **Easy integration** with NumPy and pandas workflows
43
+ - **Production ready** - Comprehensive testing across Python 3.9-3.13
44
+
45
+ ## Quick Links
46
+
47
+ - [Installation](installation.md) - How to install Edsger
48
+ - [Quick Start](quickstart.md) - Get started quickly with basic examples
49
+ - [API Reference](api.md) - Complete API reference
50
+
51
+ ## Table of Contents
52
+
53
+ ```{toctree}
54
+ :maxdepth: 2
55
+ :caption: User Guide
56
+
57
+ installation
58
+ quickstart
59
+ ```
60
+
61
+ ```{toctree}
62
+ :maxdepth: 2
63
+ :caption: API Reference
64
+
65
+ api
66
+ ```
67
+
68
+ ```{toctree}
69
+ :maxdepth: 1
70
+ :caption: Development
71
+
72
+ contributing
73
+ ```
74
+
75
+ ## Indices
76
+
77
+ - {ref}`genindex`
78
+ - {ref}`modindex`
79
+ - {ref}`search`
80
+
@@ -2,22 +2,27 @@
2
2
 
3
3
  Welcome to our Python library for graph algorithms. So far, the library only includes Dijkstra's algorithm but we should add a range of common path algorithms later. It is also open-source and easy to integrate with other Python libraries.
4
4
 
5
- ## Dijkstra's Algorithm
6
5
 
7
- To use Dijkstra's algorithm, you can import the `Dijkstra` class from the `path` module. The function takes a graph and a source node as input, and returns the shortest path from the source node to all other nodes in the graph.
6
+ ## Graph Data Format
7
+
8
+ Edsger expects graph data as a pandas DataFrame with the following structure:
9
+
10
+ | Column | Type | Description |
11
+ |--------|---------|--------------------------------------|
12
+ | tail | int | Source vertex ID |
13
+ | head | int | Destination vertex ID |
14
+ | weight | float | Edge weight (must be non-negative) |
8
15
 
16
+ Example:
9
17
  ```python
10
18
  import pandas as pd
11
19
 
12
- from edsger.path import Dijkstra
13
-
14
- # Create a DataFrame with the edges of the graph
15
20
  edges = pd.DataFrame({
16
- 'tail': [0, 0, 1, 2, 2, 3],
17
- 'head': [1, 2, 2, 3, 4, 4],
18
- 'weight': [1, 4, 2, 1, 3, 1]
21
+ 'tail': [0, 0, 1, 2],
22
+ 'head': [1, 2, 2, 3],
23
+ 'weight': [1.0, 4.0, 2.0, 1.0]
19
24
  })
20
- edges
25
+ edsges
21
26
  ```
22
27
 
23
28
  | | tail | head | weight |
@@ -26,8 +31,32 @@ edges
26
31
  | 1 | 0 | 2 | 4 |
27
32
  | 2 | 1 | 2 | 2 |
28
33
  | 3 | 2 | 3 | 1 |
29
- | 4 | 2 | 4 | 3 |
30
- | 5 | 3 | 4 | 1 |
34
+
35
+
36
+ ## Dijkstra's Algorithm
37
+
38
+ To use Dijkstra's algorithm, you can import the `Dijkstra` class from the `path` module. The function takes a graph and a source node as input, and returns the shortest path from the source node to all other nodes in the graph.
39
+
40
+ ```python
41
+ from edsger.path import Dijkstra
42
+
43
+ # Create a DataFrame with the edges of the graph
44
+ edges = pd.DataFrame({
45
+ 'tail': [0, 0, 1, 2, 2, 3],
46
+ 'head': [1, 2, 2, 3, 4, 4],
47
+ 'weight': [1, 4, 2, 1.5, 3, 1]
48
+ })
49
+ edges
50
+ ```
51
+
52
+ | | tail | head | weight |
53
+ |---:|-------:|-------:|---------:|
54
+ | 0 | 0 | 1 | 1.0 |
55
+ | 1 | 0 | 2 | 4.0 |
56
+ | 2 | 1 | 2 | 2.0 |
57
+ | 3 | 2 | 3 | 1.5 |
58
+ | 4 | 2 | 4 | 3.0 |
59
+ | 5 | 3 | 4 | 1.0 |
31
60
 
32
61
 
33
62
  ```python
@@ -39,7 +68,7 @@ shortest_paths = dijkstra.run(vertex_idx=0)
39
68
  print("Shortest paths:", shortest_paths)
40
69
  ```
41
70
 
42
- Shortest paths: [0. 1. 3. 4. 5.]
71
+ Shortest paths: [0. 1. 3. 4.5 5.5]
43
72
 
44
73
  We get the shortest paths from the source node 0 to all other nodes in the graph. The output is an array with the shortest path length to each node. A path length is the sum of the weights of the edges in the path.
45
74
 
@@ -49,12 +78,12 @@ It is also possible to use a graph with different column names for the tail, hea
49
78
  other_edges = pd.DataFrame({
50
79
  'from': [0, 0, 1, 2, 2, 3],
51
80
  'to': [1, 2, 2, 3, 4, 4],
52
- 'travel_time': [1, 4, 2, 1, 3, 1]
81
+ 'travel_time': [1, 4, 2, 1.5, 3, 1]
53
82
  })
54
- other_dijkstra = Dijkstra(edges, tail='from', head='to', weight='travel_time')
83
+ other_dijkstra = Dijkstra(other_edges, tail='from', head='to', weight='travel_time')
55
84
  ```
56
85
 
57
- ## Orientation
86
+ ### Orientation
58
87
 
59
88
  The `orientation` argument (a string with a default value of `'out'`) specifies the orientation of the algorithm. It can be either `'out'` for single source shortest paths or `'in'` for single target shortest path.
60
89
 
@@ -68,7 +97,7 @@ print("Shortest paths:", shortest_paths)
68
97
 
69
98
  Shortest paths: [ 0. inf inf inf inf]
70
99
 
71
- ## Run Multiple Times
100
+ ### Run Multiple Times
72
101
 
73
102
  Once the Dijkstra is instantiated with a given graph and orientation, the `run` method can be called multiple times with different source vertices.
74
103
 
@@ -78,9 +107,9 @@ shortest_paths = dijkstra.run(vertex_idx=4)
78
107
  print("Shortest paths:", shortest_paths)
79
108
  ```
80
109
 
81
- Shortest paths: [5. 4. 2. 1. 0.]
110
+ Shortest paths: [5.5 4.5 2.5 1. 0. ]
82
111
 
83
- ## Check Edges
112
+ ### Check Edges
84
113
 
85
114
  The `check_edges` argument (a boolean with a default value of `False`) validates the given graph. When set to `True`, it ensures the DataFrame is well-formed by:
86
115
 
@@ -101,7 +130,7 @@ dijkstra = Dijkstra(invalid_edges, check_edges=True)
101
130
 
102
131
  ValueError: edges['weight'] should be nonnegative
103
132
 
104
- ## Permute
133
+ ### Permute
105
134
 
106
135
  Finally, the `permute` argument (boolean with a default value of `False`) allows to permute the IDs of the nodes. If set to `True`, the node IDs will be reindexed to start from 0 and be contiguous for the inner computations, and the output will be reindexed to the original IDs, loading the same result as if the IDs were not permuted. The permutation may save memory and computation time for large graphs, for example if a significant ratio of the nodes are not actually used in the graph.
107
136
 
@@ -111,7 +140,7 @@ SHIFT = 1000
111
140
  shifted_edges = pd.DataFrame({
112
141
  'tail': [0, 0, 1, 2, 2, 3],
113
142
  'head': [1, 2, 2, 3, 4, 4],
114
- 'weight': [1, 4, 2, 1, 3, 1]
143
+ 'weight': [1, 4, 2, 1.5, 3, 1]
115
144
  })
116
145
  shifted_edges["tail"] += SHIFT
117
146
  shifted_edges["head"] += SHIFT
@@ -120,9 +149,9 @@ shifted_edges.head(3)
120
149
 
121
150
  | | tail | head | weight |
122
151
  |---:|-------:|-------:|---------:|
123
- | 0 | 1000 | 1001 | 1 |
124
- | 1 | 1000 | 1002 | 4 |
125
- | 2 | 1001 | 1002 | 2 |
152
+ | 0 | 1000 | 1001 | 1.0 |
153
+ | 1 | 1000 | 1002 | 4.0 |
154
+ | 2 | 1001 | 1002 | 2.0 |
126
155
 
127
156
 
128
157
 
@@ -132,15 +161,16 @@ shortest_paths = dijkstra.run(vertex_idx=0 + SHIFT)
132
161
  print("Shortest paths:", shortest_paths)
133
162
  ```
134
163
 
135
- Shortest paths: [inf inf inf ... 3. 4. 5.]
164
+ Shortest paths: [inf inf inf ... 3. 4.5 5.5]
136
165
 
137
166
  ```python
138
167
  shortest_paths[-5:]
139
168
  ```
140
169
 
141
- array([0., 1., 3., 4., 5.])
170
+ array([0. , 1. , 3. , 4.5, 5.5])
171
+
142
172
 
143
- ## Run Method Options
173
+ ### Run Method Options
144
174
 
145
175
  The `run` method can take the following arguments besides the source/target vertex index:
146
176
 
@@ -190,11 +220,11 @@ shortest_paths
190
220
 
191
221
  | vertex_idx | path_length |
192
222
  |-------------:|--------------:|
193
- | 0 | 5 |
194
- | 1 | 4 |
195
- | 2 | 2 |
196
- | 3 | 1 |
197
- | 4 | 0 |
223
+ | 0 | 5.5 |
224
+ | 1 | 4.5 |
225
+ | 2 | 2.5 |
226
+ | 3 | 1.0 |
227
+ | 4 | 0.0 |
198
228
 
199
229
 
200
230
  - `heap_length_ratio` : float, optional (default=1.0)
@@ -7,7 +7,7 @@ name = "edsger"
7
7
  dynamic = ["version"]
8
8
  description = "Graph algorithms in Cython."
9
9
  readme = "README.md"
10
- requires-python = ">=3.11"
10
+ requires-python = ">=3.9"
11
11
  license = {text = "MIT License"}
12
12
  authors = [
13
13
  { name = "François Pacull", email = "francois.pacull@architecture-performance.fr" },
@@ -19,6 +19,11 @@ keywords = ["python", "graph", "shortest path", "Dijkstra"]
19
19
  classifiers = [
20
20
  "Development Status :: 4 - Beta",
21
21
  "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.9",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
22
27
  "License :: OSI Approved :: MIT License",
23
28
  "Operating System :: OS Independent",
24
29
  "Topic :: Scientific/Engineering"
@@ -61,4 +66,8 @@ write_to_template = '__version__ = "{version}"'
61
66
  [tool.pytest.ini_options]
62
67
  testpaths = [
63
68
  "tests"
64
- ]
69
+ ]
70
+
71
+ [tool.cibuildwheel]
72
+ # Skip 32-bit i686 architectures (outdated, rarely needed)
73
+ skip = "*_i686"
@@ -4,12 +4,15 @@
4
4
  # Testing
5
5
  scipy
6
6
  pytest
7
+ pytest-cov
7
8
 
8
9
  # Scripts
9
10
  loguru
10
11
  pyarrow
11
12
 
12
13
  # Linting/Tooling
14
+ cython-lint
15
+ black
13
16
 
14
17
  # Documentation
15
18
  sphinx