edsger 0.1.4__cp310-cp310-win32.whl → 0.1.6__cp310-cp310-win32.whl
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.
- edsger/_version.py +1 -1
- edsger/bellman_ford.cp310-win32.pyd +0 -0
- edsger/bellman_ford.pyx +551 -0
- edsger/bfs.cp310-win32.pyd +0 -0
- edsger/bfs.pyx +243 -0
- edsger/commons.cp310-win32.pyd +0 -0
- edsger/commons.pyx +7 -0
- edsger/dijkstra.cp310-win32.pyd +0 -0
- edsger/dijkstra.pyx +7 -0
- edsger/graph_importer.py +340 -0
- edsger/networks.py +4 -2
- edsger/path.py +1410 -264
- edsger/path_tracking.cp310-win32.pyd +0 -0
- edsger/path_tracking.pyx +7 -0
- edsger/pq_4ary_dec_0b.cp310-win32.pyd +0 -0
- edsger/pq_4ary_dec_0b.pyx +7 -0
- edsger/spiess_florian.cp310-win32.pyd +0 -0
- edsger/spiess_florian.pyx +7 -0
- edsger/star.cp310-win32.pyd +0 -0
- edsger/star.pyx +7 -0
- edsger/utils.py +69 -4
- edsger-0.1.6.dist-info/METADATA +304 -0
- edsger-0.1.6.dist-info/RECORD +32 -0
- edsger-0.1.4.dist-info/METADATA +0 -125
- edsger-0.1.4.dist-info/RECORD +0 -27
- {edsger-0.1.4.dist-info → edsger-0.1.6.dist-info}/WHEEL +0 -0
- {edsger-0.1.4.dist-info → edsger-0.1.6.dist-info}/licenses/AUTHORS.rst +0 -0
- {edsger-0.1.4.dist-info → edsger-0.1.6.dist-info}/licenses/LICENSE +0 -0
- {edsger-0.1.4.dist-info → edsger-0.1.6.dist-info}/top_level.txt +0 -0
Binary file
|
edsger/path_tracking.pyx
CHANGED
@@ -14,6 +14,13 @@ cdef functions:
|
|
14
14
|
Compute the sequence of vertices forming a path.
|
15
15
|
"""
|
16
16
|
|
17
|
+
# cython: language_level=3
|
18
|
+
# cython: boundscheck=False
|
19
|
+
# cython: wraparound=False
|
20
|
+
# cython: embedsignature=False
|
21
|
+
# cython: cdivision=True
|
22
|
+
# cython: initializedcheck=False
|
23
|
+
|
17
24
|
import numpy as np
|
18
25
|
cimport numpy as cnp
|
19
26
|
|
Binary file
|
edsger/pq_4ary_dec_0b.pyx
CHANGED
@@ -35,6 +35,13 @@ cdef functions:
|
|
35
35
|
|
36
36
|
"""
|
37
37
|
|
38
|
+
# cython: language_level=3
|
39
|
+
# cython: boundscheck=False
|
40
|
+
# cython: wraparound=False
|
41
|
+
# cython: embedsignature=False
|
42
|
+
# cython: cdivision=True
|
43
|
+
# cython: initializedcheck=False
|
44
|
+
|
38
45
|
cimport numpy as cnp
|
39
46
|
from libc.stdlib cimport free, malloc
|
40
47
|
|
Binary file
|
edsger/spiess_florian.pyx
CHANGED
@@ -17,6 +17,13 @@ cdef functions:
|
|
17
17
|
|
18
18
|
"""
|
19
19
|
|
20
|
+
# cython: language_level=3
|
21
|
+
# cython: boundscheck=False
|
22
|
+
# cython: wraparound=False
|
23
|
+
# cython: embedsignature=False
|
24
|
+
# cython: cdivision=True
|
25
|
+
# cython: initializedcheck=False
|
26
|
+
|
20
27
|
import numpy as np
|
21
28
|
cimport numpy as cnp
|
22
29
|
|
edsger/star.cp310-win32.pyd
CHANGED
Binary file
|
edsger/star.pyx
CHANGED
@@ -26,6 +26,13 @@ cdef functions:
|
|
26
26
|
- _coo_to_csc_float64
|
27
27
|
"""
|
28
28
|
|
29
|
+
# cython: language_level=3
|
30
|
+
# cython: boundscheck=False
|
31
|
+
# cython: wraparound=False
|
32
|
+
# cython: embedsignature=False
|
33
|
+
# cython: cdivision=True
|
34
|
+
# cython: initializedcheck=False
|
35
|
+
|
29
36
|
import numpy as np
|
30
37
|
cimport numpy as cnp
|
31
38
|
|
edsger/utils.py
CHANGED
@@ -2,11 +2,20 @@
|
|
2
2
|
graphs.
|
3
3
|
"""
|
4
4
|
|
5
|
+
from typing import Tuple
|
5
6
|
import numpy as np
|
6
7
|
import pandas as pd
|
7
8
|
|
8
9
|
|
9
|
-
def generate_random_network(
|
10
|
+
def generate_random_network(
|
11
|
+
n_edges: int = 100,
|
12
|
+
n_verts: int = 20,
|
13
|
+
seed: int = 124,
|
14
|
+
sort: bool = True,
|
15
|
+
allow_negative_weights: bool = False,
|
16
|
+
negative_weight_ratio: float = 0.3,
|
17
|
+
weight_range: Tuple[float, float] = (0.1, 1.0),
|
18
|
+
) -> pd.DataFrame:
|
10
19
|
"""
|
11
20
|
Generate a random network with a specified number of edges and vertices.
|
12
21
|
|
@@ -20,6 +29,14 @@ def generate_random_network(n_edges=100, n_verts=20, seed=124, sort=True):
|
|
20
29
|
The seed for the random number generator. Default is 124.
|
21
30
|
sort : bool, optional
|
22
31
|
Whether to sort the edges by tail and head vertices. Default is True.
|
32
|
+
allow_negative_weights : bool, optional
|
33
|
+
Whether to allow negative edge weights. Default is False (positive weights only).
|
34
|
+
negative_weight_ratio : float, optional
|
35
|
+
Proportion of edges that should have negative weights when allow_negative_weights=True.
|
36
|
+
Must be between 0.0 and 1.0. Default is 0.3 (30% negative).
|
37
|
+
weight_range : tuple of float, optional
|
38
|
+
Range of absolute values for weights as (min, max). Default is (0.1, 1.0).
|
39
|
+
When allow_negative_weights=True, negative weights will be in range (-max, -min).
|
23
40
|
|
24
41
|
Returns
|
25
42
|
-------
|
@@ -28,6 +45,8 @@ def generate_random_network(n_edges=100, n_verts=20, seed=124, sort=True):
|
|
28
45
|
|
29
46
|
Examples
|
30
47
|
--------
|
48
|
+
Generate a graph with positive weights only (default):
|
49
|
+
|
31
50
|
>>> generate_random_network(n_edges=5, n_verts=3, seed=42)
|
32
51
|
tail head weight
|
33
52
|
0 0 2 0.975622
|
@@ -36,20 +55,66 @@ def generate_random_network(n_edges=100, n_verts=20, seed=124, sort=True):
|
|
36
55
|
3 1 2 0.786064
|
37
56
|
4 2 0 0.761140
|
38
57
|
|
58
|
+
Generate a graph with mixed positive and negative weights:
|
59
|
+
|
60
|
+
>>> generate_random_network(n_edges=5, n_verts=3, seed=42,
|
61
|
+
... allow_negative_weights=True, negative_weight_ratio=0.4)
|
62
|
+
tail head weight
|
63
|
+
0 0 2 0.975622
|
64
|
+
1 1 0 -0.128114
|
65
|
+
2 1 0 0.450386
|
66
|
+
3 1 2 -0.786064
|
67
|
+
4 2 0 0.761140
|
39
68
|
|
40
69
|
Notes
|
41
70
|
-----
|
42
71
|
The 'tail' and 'head' columns represent the source and destination vertices of each edge,
|
43
|
-
respectively. The 'weight' column represents the weight of each edge
|
44
|
-
|
72
|
+
respectively. The 'weight' column represents the weight of each edge.
|
73
|
+
|
74
|
+
When allow_negative_weights=False (default), weights are random floats between
|
75
|
+
weight_range[0] and weight_range[1].
|
76
|
+
|
77
|
+
When allow_negative_weights=True, approximately negative_weight_ratio proportion of edges
|
78
|
+
will have negative weights, useful for testing algorithms like Bellman-Ford that support
|
79
|
+
negative edge weights.
|
45
80
|
|
46
81
|
If `sort` is True, the DataFrame is sorted by the 'tail' and 'head' columns and the index
|
47
82
|
is reset.
|
48
83
|
"""
|
84
|
+
# Validate parameters
|
85
|
+
if not 0.0 <= negative_weight_ratio <= 1.0:
|
86
|
+
raise ValueError("negative_weight_ratio must be between 0.0 and 1.0")
|
87
|
+
if (
|
88
|
+
len(weight_range) != 2
|
89
|
+
or weight_range[0] <= 0
|
90
|
+
or weight_range[1] <= weight_range[0]
|
91
|
+
):
|
92
|
+
raise ValueError("weight_range must be (min, max) with 0 < min < max")
|
93
|
+
|
49
94
|
rng = np.random.default_rng(seed=seed)
|
50
95
|
tail = rng.integers(low=0, high=n_verts, size=n_edges)
|
51
96
|
head = rng.integers(low=0, high=n_verts, size=n_edges)
|
52
|
-
|
97
|
+
|
98
|
+
# Generate weights
|
99
|
+
if allow_negative_weights:
|
100
|
+
# Generate weights in the specified range
|
101
|
+
weight = rng.uniform(low=weight_range[0], high=weight_range[1], size=n_edges)
|
102
|
+
|
103
|
+
# Randomly select edges to have negative weights
|
104
|
+
n_negative = int(n_edges * negative_weight_ratio)
|
105
|
+
if n_negative > 0:
|
106
|
+
negative_indices = rng.choice(n_edges, size=n_negative, replace=False)
|
107
|
+
weight[negative_indices] *= -1
|
108
|
+
else:
|
109
|
+
# Original behavior: positive weights in range [weight_range[0], weight_range[1]]
|
110
|
+
if weight_range == (0.1, 1.0):
|
111
|
+
# Keep backward compatibility for default case
|
112
|
+
weight = rng.random(size=n_edges)
|
113
|
+
else:
|
114
|
+
weight = rng.uniform(
|
115
|
+
low=weight_range[0], high=weight_range[1], size=n_edges
|
116
|
+
)
|
117
|
+
|
53
118
|
edges = pd.DataFrame(data={"tail": tail, "head": head, "weight": weight})
|
54
119
|
if sort:
|
55
120
|
edges.sort_values(by=["tail", "head"], inplace=True)
|
@@ -0,0 +1,304 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: edsger
|
3
|
+
Version: 0.1.6
|
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
|
+

|
44
|
+
[](https://codecov.io/gh/aetperf/edsger)
|
45
|
+
[](https://edsger.readthedocs.io/en/latest/?badge=latest)
|
46
|
+
[](https://pypi.org/project/edsger/)
|
47
|
+
[](https://pepy.tech/project/edsger)
|
48
|
+
[](https://pypi.org/project/edsger/)
|
49
|
+
[](https://github.com/psf/black)
|
50
|
+
[](https://github.com/MarcoGorelli/cython-lint)
|
51
|
+
[](https://microsoft.github.io/pyright/)
|
52
|
+
[](https://opensource.org/licenses/MIT)
|
53
|
+
|
54
|
+
# Edsger
|
55
|
+
|
56
|
+
*Graph algorithms in Cython*
|
57
|
+
|
58
|
+
Welcome to our Python library for graph algorithms. The library includes both Dijkstra's and Bellman-Ford's algorithms, with plans to add more 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.
|
59
|
+
|
60
|
+
Documentation : [https://edsger.readthedocs.io/en/latest/](https://edsger.readthedocs.io/en/latest/)
|
61
|
+
|
62
|
+
## Small example : Dijkstra's Algorithm
|
63
|
+
|
64
|
+
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.
|
65
|
+
|
66
|
+
```python
|
67
|
+
import pandas as pd
|
68
|
+
|
69
|
+
from edsger.path import Dijkstra
|
70
|
+
|
71
|
+
# Create a DataFrame with the edges of the graph
|
72
|
+
edges = pd.DataFrame({
|
73
|
+
'tail': [0, 0, 1, 2, 2, 3],
|
74
|
+
'head': [1, 2, 2, 3, 4, 4],
|
75
|
+
'weight': [1, 4, 2, 1.5, 3, 1]
|
76
|
+
})
|
77
|
+
edges
|
78
|
+
```
|
79
|
+
|
80
|
+
| | tail | head | weight |
|
81
|
+
|---:|-------:|-------:|---------:|
|
82
|
+
| 0 | 0 | 1 | 1.0 |
|
83
|
+
| 1 | 0 | 2 | 4.0 |
|
84
|
+
| 2 | 1 | 2 | 2.0 |
|
85
|
+
| 3 | 2 | 3 | 1.5 |
|
86
|
+
| 4 | 2 | 4 | 3.0 |
|
87
|
+
| 5 | 3 | 4 | 1.0 |
|
88
|
+
|
89
|
+
```python
|
90
|
+
# Initialize the Dijkstra object
|
91
|
+
dijkstra = Dijkstra(edges)
|
92
|
+
|
93
|
+
# Run the algorithm from a source vertex
|
94
|
+
shortest_paths = dijkstra.run(vertex_idx=0)
|
95
|
+
print("Shortest paths:", shortest_paths)
|
96
|
+
```
|
97
|
+
|
98
|
+
Shortest paths: [0. 1. 3. 4.5 5.5]
|
99
|
+
|
100
|
+
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.
|
101
|
+
|
102
|
+
## Bellman-Ford Algorithm: Handling Negative Weights
|
103
|
+
|
104
|
+
The Bellman-Ford algorithm can handle graphs with negative edge weights and detect negative cycles, making it suitable for more complex scenarios than Dijkstra's algorithm.
|
105
|
+
|
106
|
+
```python
|
107
|
+
from edsger.path import BellmanFord
|
108
|
+
|
109
|
+
# Create a graph with negative weights
|
110
|
+
edges_negative = pd.DataFrame({
|
111
|
+
'tail': [0, 0, 1, 1, 2, 3],
|
112
|
+
'head': [1, 2, 2, 3, 3, 4],
|
113
|
+
'weight': [1, 4, -2, 5, 1, 3] # Note the negative weight
|
114
|
+
})
|
115
|
+
edges_negative
|
116
|
+
```
|
117
|
+
|
118
|
+
| | tail | head | weight |
|
119
|
+
|---:|-------:|-------:|---------:|
|
120
|
+
| 0 | 0 | 1 | 1.0 |
|
121
|
+
| 1 | 0 | 2 | 4.0 |
|
122
|
+
| 2 | 1 | 2 | -2.0 |
|
123
|
+
| 3 | 1 | 3 | 5.0 |
|
124
|
+
| 4 | 2 | 3 | 1.0 |
|
125
|
+
| 5 | 3 | 4 | 3.0 |
|
126
|
+
|
127
|
+
```python
|
128
|
+
# Initialize and run Bellman-Ford
|
129
|
+
bf = BellmanFord(edges_negative)
|
130
|
+
shortest_paths = bf.run(vertex_idx=0)
|
131
|
+
print("Shortest paths:", shortest_paths)
|
132
|
+
```
|
133
|
+
|
134
|
+
Shortest paths: [ 0. 1. -1. 0. 3.]
|
135
|
+
|
136
|
+
The Bellman-Ford algorithm finds the optimal path even with negative weights. In this example, the shortest path from node 0 to node 2 has length -1 (going 0→1→2 with weights 1 + (-2) = -1), which is shorter than the direct path 0→2 with weight 4.
|
137
|
+
|
138
|
+
### Negative Cycle Detection
|
139
|
+
|
140
|
+
Bellman-Ford can also detect negative cycles, which indicate that no shortest path exists:
|
141
|
+
|
142
|
+
```python
|
143
|
+
# Create a graph with a negative cycle
|
144
|
+
edges_cycle = pd.DataFrame({
|
145
|
+
'tail': [0, 1, 2],
|
146
|
+
'head': [1, 2, 0],
|
147
|
+
'weight': [1, -2, -1] # Cycle 0→1→2→0 has total weight -2
|
148
|
+
})
|
149
|
+
|
150
|
+
bf_cycle = BellmanFord(edges_cycle)
|
151
|
+
try:
|
152
|
+
bf_cycle.run(vertex_idx=0)
|
153
|
+
except ValueError as e:
|
154
|
+
print("Error:", e)
|
155
|
+
```
|
156
|
+
|
157
|
+
Error: Negative cycle detected in the graph
|
158
|
+
|
159
|
+
## Breadth-First Search: Unweighted Directed Graphs
|
160
|
+
|
161
|
+
The BFS (Breadth-First Search) algorithm finds shortest paths in directed graphs where edge weights are ignored (or all edges are treated as having equal weight). It's particularly efficient for finding paths based on the minimum number of hops/edges rather than weighted distances.
|
162
|
+
|
163
|
+
```python
|
164
|
+
from edsger.path import BFS
|
165
|
+
|
166
|
+
# Create an unweighted directed graph
|
167
|
+
edges_unweighted = pd.DataFrame({
|
168
|
+
'tail': [0, 0, 1, 2, 2, 3],
|
169
|
+
'head': [1, 2, 3, 3, 4, 4]
|
170
|
+
})
|
171
|
+
edges_unweighted
|
172
|
+
```
|
173
|
+
|
174
|
+
| | tail | head |
|
175
|
+
|---:|-------:|-------:|
|
176
|
+
| 0 | 0 | 1 |
|
177
|
+
| 1 | 0 | 2 |
|
178
|
+
| 2 | 1 | 3 |
|
179
|
+
| 3 | 2 | 3 |
|
180
|
+
| 4 | 2 | 4 |
|
181
|
+
| 5 | 3 | 4 |
|
182
|
+
|
183
|
+
```python
|
184
|
+
# Initialize BFS
|
185
|
+
bfs = BFS(edges_unweighted)
|
186
|
+
|
187
|
+
# Run BFS from vertex 0 with path tracking
|
188
|
+
predecessors = bfs.run(vertex_idx=0, path_tracking=True)
|
189
|
+
print("Predecessors:", predecessors)
|
190
|
+
|
191
|
+
# Extract the path to vertex 4
|
192
|
+
path = bfs.get_path(4)
|
193
|
+
print("Path from 0 to 4:", path)
|
194
|
+
```
|
195
|
+
|
196
|
+
Predecessors: [-9999 0 0 1 2]
|
197
|
+
Path from 0 to 4: [4 2 0]
|
198
|
+
|
199
|
+
The BFS algorithm is ideal for directed graphs when:
|
200
|
+
- All edges should be treated equally (ignoring edge weights)
|
201
|
+
- You need to find paths with the minimum number of edges/hops
|
202
|
+
- You want the fastest path-finding algorithm for unweighted directed graphs (O(V + E) time complexity)
|
203
|
+
|
204
|
+
Note: The predecessor value -9999 indicates either the start vertex or an unreachable vertex. In the path output, vertices are listed from target to source.
|
205
|
+
|
206
|
+
## Installation
|
207
|
+
|
208
|
+
### Standard Installation
|
209
|
+
|
210
|
+
```bash
|
211
|
+
pip install edsger
|
212
|
+
```
|
213
|
+
|
214
|
+
### Development Installation
|
215
|
+
|
216
|
+
For development work, clone the repository and install in development mode:
|
217
|
+
|
218
|
+
```bash
|
219
|
+
git clone https://github.com/aetperf/Edsger.git
|
220
|
+
cd Edsger
|
221
|
+
pip install -r requirements-dev.txt
|
222
|
+
pip install -e .
|
223
|
+
```
|
224
|
+
|
225
|
+
## Development
|
226
|
+
|
227
|
+
This project uses several development tools to ensure code quality:
|
228
|
+
|
229
|
+
### Type Checking
|
230
|
+
|
231
|
+
We use [Pyright](https://github.com/microsoft/pyright) for static type checking:
|
232
|
+
|
233
|
+
```bash
|
234
|
+
# Run type checking
|
235
|
+
make typecheck
|
236
|
+
|
237
|
+
# Or directly with pyright
|
238
|
+
pyright
|
239
|
+
```
|
240
|
+
|
241
|
+
For more details on type checking configuration and gradual typing strategy, see [TYPING.md](TYPING.md).
|
242
|
+
|
243
|
+
### Running Tests
|
244
|
+
|
245
|
+
```bash
|
246
|
+
# Run all tests
|
247
|
+
make test
|
248
|
+
|
249
|
+
# Run with coverage
|
250
|
+
make coverage
|
251
|
+
```
|
252
|
+
|
253
|
+
### Code Formatting and Linting
|
254
|
+
|
255
|
+
```bash
|
256
|
+
# Format code with black
|
257
|
+
make format
|
258
|
+
|
259
|
+
# Check code style
|
260
|
+
make lint
|
261
|
+
```
|
262
|
+
|
263
|
+
### Pre-commit Hooks
|
264
|
+
|
265
|
+
This project uses pre-commit hooks to maintain code quality. The hooks behave differently based on the branch:
|
266
|
+
|
267
|
+
- **Protected branches (main, release*)**: All hooks run including pyright type checking
|
268
|
+
- **Feature branches**: Only formatting hooks run (black, cython-lint) for faster commits
|
269
|
+
- Run `make typecheck` or `pre-commit run --all-files` to manually check types before merging
|
270
|
+
|
271
|
+
```bash
|
272
|
+
# Install pre-commit hooks
|
273
|
+
pre-commit install
|
274
|
+
|
275
|
+
# Run all hooks manually
|
276
|
+
pre-commit run --all-files
|
277
|
+
|
278
|
+
# Skip specific hooks if needed
|
279
|
+
SKIP=pyright git commit -m "your message"
|
280
|
+
```
|
281
|
+
|
282
|
+
### Available Make Commands
|
283
|
+
|
284
|
+
```bash
|
285
|
+
make help # Show all available commands
|
286
|
+
```
|
287
|
+
|
288
|
+
## Why Use Edsger?
|
289
|
+
|
290
|
+
Edsger is designed to be **dataframe-friendly**, providing seamless integration with pandas workflows for graph algorithms. Also it is rather efficient on Linux. Our benchmarks on the USA road network (23.9M vertices, 57.7M edges) demonstrate nice performance:
|
291
|
+
|
292
|
+
<img src="https://raw.githubusercontent.com/aetperf/edsger/release/docs/source/assets/dijkstra_benchmark_comparison.png" alt="Dijkstra Performance Comparison" width="700">
|
293
|
+
|
294
|
+
## Contributing
|
295
|
+
|
296
|
+
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).
|
297
|
+
|
298
|
+
## License
|
299
|
+
|
300
|
+
Edsger is licensed under the MIT License. See the LICENSE file for more details.
|
301
|
+
|
302
|
+
## Contact
|
303
|
+
|
304
|
+
For any questions or inquiries, please contact me at [francois.pacull@architecture-performance.fr](mailto:francois.pacull@architecture-performance.fr).
|
@@ -0,0 +1,32 @@
|
|
1
|
+
edsger/.gitignore,sha256=mr9Izcwvjgv215xjRKhWEZ7vsyrKWhMqvWjSLHRYDjk,13
|
2
|
+
edsger/__init__.py,sha256=lgtGe3cqdwWdO1DLEOx7fX3i8D4Z_2rXHSq7Xecf-NM,41
|
3
|
+
edsger/_version.py,sha256=l1lWRV5fzx6-C3xpWdEYCx3Y5TNykf_HgoEs12q6cfQ,21
|
4
|
+
edsger/bellman_ford.cp310-win32.pyd,sha256=DN32kXF98rI3eRYe9EYAqHoEkf805yp_eh6lBf_CuUY,155648
|
5
|
+
edsger/bellman_ford.pyx,sha256=kscWdAKBhL9TC44PzWbHhMfkIYq6vvSW_DM8UWlnPeI,17607
|
6
|
+
edsger/bfs.cp310-win32.pyd,sha256=dPyFzqYPdy2VE6yNVt5CV5HaI2WtKPTSD6qf55xxdS0,140800
|
7
|
+
edsger/bfs.pyx,sha256=UJsghsI_1IEAxxTYSSsu-v9lxRP2nTEBUH2m4bX9qkg,8011
|
8
|
+
edsger/commons.cp310-win32.pyd,sha256=0JUilA265gzYU2Ax2U25yPnZtPUR13wZrLPnqF_j4qk,20480
|
9
|
+
edsger/commons.pxd,sha256=UshKjr5ve3Or9u75xGyGPKRz1RwCCb5N-xgNevXZ4j4,464
|
10
|
+
edsger/commons.pyx,sha256=rj7A-6soxKrONHOncaujC3ameKJVe1LhfD6s8RI5CDo,1018
|
11
|
+
edsger/dijkstra.cp310-win32.pyd,sha256=UF9CS9aARhMP6oF8G2bKKdEhubIy371oL-4iD9ObVDw,213504
|
12
|
+
edsger/dijkstra.pyx,sha256=K_jQ4U-sBy72o3anyRHeOUHKILmb22eXkhDlLqgfXfk,37721
|
13
|
+
edsger/graph_importer.py,sha256=wvvwzlW5edjHhVIbfK7sObHPNbbCSsD8I6co-NZ8EG4,11825
|
14
|
+
edsger/networks.py,sha256=RquMB0TXKx_8hupuKaVQ57NCV0X9dfkvkQcNxJF1RyQ,10788
|
15
|
+
edsger/path.py,sha256=5XOs4H4c4oqmVHwpLybzz1NzebJRs_HEUAN7kGr3gS0,80917
|
16
|
+
edsger/path_tracking.cp310-win32.pyd,sha256=0wM43MOKauFRTYmGYSVmvzM0_SjsEpL40mamqVmM0Fg,111104
|
17
|
+
edsger/path_tracking.pyx,sha256=DlCgv6B8qGYQCut6EXMb1Ck7Cz3pHLiAHgOiagUQ1Es,2079
|
18
|
+
edsger/pq_4ary_dec_0b.cp310-win32.pyd,sha256=HiLLsW231ORjV3l1IVrMhFxvhCU1KiUA6oDfu_5YaRw,134656
|
19
|
+
edsger/pq_4ary_dec_0b.pxd,sha256=VvXcQzJq3OGBptrbawtemagPimuqSCayGQ91Jrad894,1098
|
20
|
+
edsger/pq_4ary_dec_0b.pyx,sha256=EnKhqiob4Jm0IOq2nQ4Qx0PykcKNq8IeuHY5mu2FkGk,18665
|
21
|
+
edsger/prefetch_compat.h,sha256=AyAYq_ZHKk5ChaJDrZOAOYe6SprL0_2byjRbjcBGrsU,826
|
22
|
+
edsger/spiess_florian.cp310-win32.pyd,sha256=8CTZgqpMCtHqYyCsJY6eicfhQakXf3VNyRT1U0bxgFI,163840
|
23
|
+
edsger/spiess_florian.pyx,sha256=7gsd8vLjwA2r7NPxKVYC3Fenm-31KZP8Ttui1o5A1bU,10113
|
24
|
+
edsger/star.cp310-win32.pyd,sha256=K8NKs6xF-zHVoUFgpA30h_PHBsum25sKikZ_mczk1UI,153600
|
25
|
+
edsger/star.pyx,sha256=2leWr-5LYI6r7zFVbfJ-aVrt77exqurQDvA3plHSNNQ,9781
|
26
|
+
edsger/utils.py,sha256=YgSDAxAlhXv9bhKs60d-6S_l83Kt2KwBU-38PjUcO6s,4839
|
27
|
+
edsger-0.1.6.dist-info/licenses/AUTHORS.rst,sha256=8udN6bgZHdHYcVzV38y6SPnF-x6Ks0uXxxFsic6Aces,110
|
28
|
+
edsger-0.1.6.dist-info/licenses/LICENSE,sha256=w7gRlruGxK3_4KTZAyJsOR2tML4UQgB-GNm2LerwJS0,1132
|
29
|
+
edsger-0.1.6.dist-info/METADATA,sha256=KwQ635ZRYrTqoSpo4-JSpeIn-c5BeyvLa4HhQ9wxIrE,10562
|
30
|
+
edsger-0.1.6.dist-info/WHEEL,sha256=GWZF0cboiU4MhsG0baPl8rrtCaXFSLW25384gp3vddM,97
|
31
|
+
edsger-0.1.6.dist-info/top_level.txt,sha256=QvhzFORJIIot6GzSnDrtGa9KQt9iifCbOC5ULlzY5dg,7
|
32
|
+
edsger-0.1.6.dist-info/RECORD,,
|
edsger-0.1.4.dist-info/METADATA
DELETED
@@ -1,125 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: edsger
|
3
|
-
Version: 0.1.4
|
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
|
-

|
44
|
-
[](https://codecov.io/gh/aetperf/edsger)
|
45
|
-
[](https://edsger.readthedocs.io/en/latest/?badge=latest)
|
46
|
-
[](https://pypi.org/project/edsger/)
|
47
|
-
[](https://pepy.tech/project/edsger)
|
48
|
-
[](https://pypi.org/project/edsger/)
|
49
|
-
[](https://github.com/psf/black)
|
50
|
-
[](https://github.com/MarcoGorelli/cython-lint)
|
51
|
-
[](https://opensource.org/licenses/MIT)
|
52
|
-
|
53
|
-
# Edsger
|
54
|
-
|
55
|
-
*Graph algorithms in Cython*
|
56
|
-
|
57
|
-
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.
|
58
|
-
|
59
|
-
Documentation : [https://edsger.readthedocs.io/en/latest/](https://edsger.readthedocs.io/en/latest/)
|
60
|
-
|
61
|
-
## Small example : Dijkstra's Algorithm
|
62
|
-
|
63
|
-
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.
|
64
|
-
|
65
|
-
```python
|
66
|
-
import pandas as pd
|
67
|
-
|
68
|
-
from edsger.path import Dijkstra
|
69
|
-
|
70
|
-
# Create a DataFrame with the edges of the graph
|
71
|
-
edges = pd.DataFrame({
|
72
|
-
'tail': [0, 0, 1, 2, 2, 3],
|
73
|
-
'head': [1, 2, 2, 3, 4, 4],
|
74
|
-
'weight': [1, 4, 2, 1.5, 3, 1]
|
75
|
-
})
|
76
|
-
edges
|
77
|
-
```
|
78
|
-
|
79
|
-
| | tail | head | weight |
|
80
|
-
|---:|-------:|-------:|---------:|
|
81
|
-
| 0 | 0 | 1 | 1.0 |
|
82
|
-
| 1 | 0 | 2 | 4.0 |
|
83
|
-
| 2 | 1 | 2 | 2.0 |
|
84
|
-
| 3 | 2 | 3 | 1.5 |
|
85
|
-
| 4 | 2 | 4 | 3.0 |
|
86
|
-
| 5 | 3 | 4 | 1.0 |
|
87
|
-
|
88
|
-
```python
|
89
|
-
# Initialize the Dijkstra object
|
90
|
-
dijkstra = Dijkstra(edges)
|
91
|
-
|
92
|
-
# Run the algorithm from a source vertex
|
93
|
-
shortest_paths = dijkstra.run(vertex_idx=0)
|
94
|
-
print("Shortest paths:", shortest_paths)
|
95
|
-
```
|
96
|
-
|
97
|
-
Shortest paths: [0. 1. 3. 4.5 5.5]
|
98
|
-
|
99
|
-
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.
|
100
|
-
|
101
|
-
## Installation
|
102
|
-
|
103
|
-
### Standard Installation
|
104
|
-
|
105
|
-
```bash
|
106
|
-
pip install edsger
|
107
|
-
```
|
108
|
-
|
109
|
-
## Why Use Edsger?
|
110
|
-
|
111
|
-
Edsger is designed to be **dataframe-friendly**, providing seamless integration with pandas workflows for graph algorithms. Also it is rather efficient on Linux. Our benchmarks on the USA road network (23.9M vertices, 57.7M edges) demonstrate nice performance:
|
112
|
-
|
113
|
-
<img src="https://raw.githubusercontent.com/aetperf/edsger/release/docs/source/assets/dijkstra_benchmark_comparison.png" alt="Dijkstra Performance Comparison" width="700">
|
114
|
-
|
115
|
-
## Contributing
|
116
|
-
|
117
|
-
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).
|
118
|
-
|
119
|
-
## License
|
120
|
-
|
121
|
-
Edsger is licensed under the MIT License. See the LICENSE file for more details.
|
122
|
-
|
123
|
-
## Contact
|
124
|
-
|
125
|
-
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.4.dist-info/RECORD
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
edsger/.gitignore,sha256=mr9Izcwvjgv215xjRKhWEZ7vsyrKWhMqvWjSLHRYDjk,13
|
2
|
-
edsger/__init__.py,sha256=lgtGe3cqdwWdO1DLEOx7fX3i8D4Z_2rXHSq7Xecf-NM,41
|
3
|
-
edsger/_version.py,sha256=JMD28FXYHc_TM03visyUSd3UA9FZAaJMRStnfZoq50Y,21
|
4
|
-
edsger/commons.cp310-win32.pyd,sha256=4zNQdY5e2ps0Pc-kCINkLOPWZ22ZQqypq_1larYvJK4,20480
|
5
|
-
edsger/commons.pxd,sha256=UshKjr5ve3Or9u75xGyGPKRz1RwCCb5N-xgNevXZ4j4,464
|
6
|
-
edsger/commons.pyx,sha256=6Ze22eE_zwXPRAe550DEhEvu-b7hvKmwQu73rzzWMUE,839
|
7
|
-
edsger/dijkstra.cp310-win32.pyd,sha256=6EfhLtylur1ClIhUHr0GrDdgI_LHHxn7eS8iKXsH4xo,208384
|
8
|
-
edsger/dijkstra.pyx,sha256=kBXFya0bugjp97xas145sZEUXtb89_Sg9v8IdWiURoE,37542
|
9
|
-
edsger/networks.py,sha256=hH9sgT5Ic4TLVCjxPNzMDWNjNDbqpXMxXxLeWxCpdLE,10730
|
10
|
-
edsger/path.py,sha256=2NtkhwN2HQUsoZn0Sl6UbFKWIcWVTvnE6D8IH-xEG88,35768
|
11
|
-
edsger/path_tracking.cp310-win32.pyd,sha256=jvjMVe0NKtCpueb7rOJTbt9fX3-rykPq8Pd6WZqw76k,110592
|
12
|
-
edsger/path_tracking.pyx,sha256=H24TLmC53I8LjbM1S5E7gS8WEb5uE_PZ8nhG6BteMYA,1900
|
13
|
-
edsger/pq_4ary_dec_0b.cp310-win32.pyd,sha256=jo3q8ebQFzRS2vNXXYk2iaNvNaHfnFA7L5LDxzZ9JrA,134656
|
14
|
-
edsger/pq_4ary_dec_0b.pxd,sha256=VvXcQzJq3OGBptrbawtemagPimuqSCayGQ91Jrad894,1098
|
15
|
-
edsger/pq_4ary_dec_0b.pyx,sha256=IzvzQerf-LYy7weQpgI0f28Q8gUrR4ENaedekXs1Jeg,18486
|
16
|
-
edsger/prefetch_compat.h,sha256=AyAYq_ZHKk5ChaJDrZOAOYe6SprL0_2byjRbjcBGrsU,826
|
17
|
-
edsger/spiess_florian.cp310-win32.pyd,sha256=7MBTUit0IKQXS7M_Wvxg3d4oW-w2j-cuyrridr6Tfig,157696
|
18
|
-
edsger/spiess_florian.pyx,sha256=tjfF9Iv8nqpp4lnv4KAjF-37ij0_SgQ0fnacVVKx-CE,9934
|
19
|
-
edsger/star.cp310-win32.pyd,sha256=LgJdAbUIlJMx9v1Rxzk1AjrF1bKQLd6FycKdXKhv57c,148992
|
20
|
-
edsger/star.pyx,sha256=9LAIXhlccEeDgT41ico7n57FJ7PKCzhPv4f22Lphn78,9602
|
21
|
-
edsger/utils.py,sha256=xYfOFIbYpAiZljhUOgGWy0TVNvWaMFCwbCLPBkzdVos,2097
|
22
|
-
edsger-0.1.4.dist-info/licenses/AUTHORS.rst,sha256=8udN6bgZHdHYcVzV38y6SPnF-x6Ks0uXxxFsic6Aces,110
|
23
|
-
edsger-0.1.4.dist-info/licenses/LICENSE,sha256=w7gRlruGxK3_4KTZAyJsOR2tML4UQgB-GNm2LerwJS0,1132
|
24
|
-
edsger-0.1.4.dist-info/METADATA,sha256=fl_OoQXbo9d0B0sIkuOSDD5JAB-CgxWA6dRNujINONc,5494
|
25
|
-
edsger-0.1.4.dist-info/WHEEL,sha256=GWZF0cboiU4MhsG0baPl8rrtCaXFSLW25384gp3vddM,97
|
26
|
-
edsger-0.1.4.dist-info/top_level.txt,sha256=QvhzFORJIIot6GzSnDrtGa9KQt9iifCbOC5ULlzY5dg,7
|
27
|
-
edsger-0.1.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|