edsger 0.1.2__cp312-cp312-macosx_11_0_arm64.whl → 0.1.3__cp312-cp312-macosx_11_0_arm64.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/commons.c +146 -146
- edsger/dijkstra.c +7058 -2696
- edsger/dijkstra.cpython-312-darwin.so +0 -0
- edsger/dijkstra.pyx +507 -5
- edsger/path.py +145 -37
- edsger/path_tracking.c +146 -146
- edsger/pq_4ary_dec_0b.c +146 -146
- edsger/spiess_florian.c +146 -146
- edsger/star.c +146 -146
- {edsger-0.1.2.dist-info → edsger-0.1.3.dist-info}/METADATA +12 -12
- {edsger-0.1.2.dist-info → edsger-0.1.3.dist-info}/RECORD +16 -16
- {edsger-0.1.2.dist-info → edsger-0.1.3.dist-info}/WHEEL +0 -0
- {edsger-0.1.2.dist-info → edsger-0.1.3.dist-info}/licenses/AUTHORS.rst +0 -0
- {edsger-0.1.2.dist-info → edsger-0.1.3.dist-info}/licenses/LICENSE +0 -0
- {edsger-0.1.2.dist-info → edsger-0.1.3.dist-info}/top_level.txt +0 -0
edsger/path.py
CHANGED
@@ -17,8 +17,12 @@ from edsger.commons import (
|
|
17
17
|
from edsger.dijkstra import (
|
18
18
|
compute_sssp,
|
19
19
|
compute_sssp_w_path,
|
20
|
+
compute_sssp_early_termination,
|
21
|
+
compute_sssp_w_path_early_termination,
|
20
22
|
compute_stsp,
|
21
23
|
compute_stsp_w_path,
|
24
|
+
compute_stsp_early_termination,
|
25
|
+
compute_stsp_w_path_early_termination,
|
22
26
|
)
|
23
27
|
from edsger.path_tracking import compute_path
|
24
28
|
from edsger.spiess_florian import compute_SF_in
|
@@ -285,6 +289,7 @@ class Dijkstra:
|
|
285
289
|
return_inf=True,
|
286
290
|
return_series=False,
|
287
291
|
heap_length_ratio=1.0,
|
292
|
+
termination_nodes=None,
|
288
293
|
):
|
289
294
|
"""
|
290
295
|
Runs shortest path algorithm between a given vertex and all other vertices in the graph.
|
@@ -303,6 +308,11 @@ class Dijkstra:
|
|
303
308
|
as values.
|
304
309
|
heap_length_ratio : float, optional (default=1.0)
|
305
310
|
The heap length as a fraction of the number of vertices. Must be in the range (0, 1].
|
311
|
+
termination_nodes : array-like, optional (default=None)
|
312
|
+
List or array of vertex indices for early termination. For SSSP (orientation='out'),
|
313
|
+
these are target nodes to reach. For STSP (orientation='in'), these are source nodes
|
314
|
+
to find paths from. When provided, the algorithm stops once all specified nodes have
|
315
|
+
been processed, potentially improving performance. If None, runs to completion.
|
306
316
|
|
307
317
|
Returns
|
308
318
|
-------
|
@@ -355,49 +365,140 @@ class Dijkstra:
|
|
355
365
|
)
|
356
366
|
heap_length = int(np.rint(heap_length_ratio * self._n_vertices))
|
357
367
|
|
368
|
+
# validate and process termination_nodes
|
369
|
+
termination_nodes_array = None
|
370
|
+
if termination_nodes is not None:
|
371
|
+
try:
|
372
|
+
termination_nodes_array = np.array(termination_nodes, dtype=np.uint32)
|
373
|
+
except (ValueError, TypeError):
|
374
|
+
raise TypeError(
|
375
|
+
"argument 'termination_nodes' must be array-like of integers"
|
376
|
+
)
|
377
|
+
|
378
|
+
if termination_nodes_array.ndim != 1:
|
379
|
+
raise ValueError("argument 'termination_nodes' must be 1-dimensional")
|
380
|
+
|
381
|
+
if len(termination_nodes_array) == 0:
|
382
|
+
raise ValueError("argument 'termination_nodes' must not be empty")
|
383
|
+
|
384
|
+
# handle vertex permutation if needed
|
385
|
+
if self._permute:
|
386
|
+
termination_nodes_permuted = []
|
387
|
+
for termination_node in termination_nodes_array:
|
388
|
+
if termination_node not in self._permutation.vert_idx_old.values:
|
389
|
+
raise ValueError(
|
390
|
+
f"termination node {termination_node} not found in graph"
|
391
|
+
)
|
392
|
+
termination_node_new = self._permutation.loc[
|
393
|
+
self._permutation.vert_idx_old == termination_node,
|
394
|
+
"vert_idx_new",
|
395
|
+
].iloc[0]
|
396
|
+
termination_nodes_permuted.append(termination_node_new)
|
397
|
+
termination_nodes_array = np.array(
|
398
|
+
termination_nodes_permuted, dtype=np.uint32
|
399
|
+
)
|
400
|
+
else:
|
401
|
+
# validate that termination nodes exist
|
402
|
+
if np.any(termination_nodes_array >= self._n_vertices) or np.any(
|
403
|
+
termination_nodes_array < 0
|
404
|
+
):
|
405
|
+
raise ValueError(
|
406
|
+
"termination_nodes contains invalid vertex indices"
|
407
|
+
)
|
408
|
+
|
358
409
|
# compute path length
|
359
410
|
if not path_tracking:
|
360
411
|
self._path_links = None
|
361
|
-
if
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
412
|
+
if termination_nodes_array is not None:
|
413
|
+
# use early termination algorithms
|
414
|
+
if self._orientation == "in":
|
415
|
+
path_length_values = compute_stsp_early_termination(
|
416
|
+
self.__indptr,
|
417
|
+
self.__indices,
|
418
|
+
self.__edge_weights,
|
419
|
+
termination_nodes_array,
|
420
|
+
vertex_new,
|
421
|
+
self._n_vertices,
|
422
|
+
heap_length,
|
423
|
+
)
|
424
|
+
else:
|
425
|
+
path_length_values = compute_sssp_early_termination(
|
426
|
+
self.__indptr,
|
427
|
+
self.__indices,
|
428
|
+
self.__edge_weights,
|
429
|
+
termination_nodes_array,
|
430
|
+
vertex_new,
|
431
|
+
self._n_vertices,
|
432
|
+
heap_length,
|
433
|
+
)
|
370
434
|
else:
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
435
|
+
# use standard algorithms
|
436
|
+
if self._orientation == "in":
|
437
|
+
path_length_values = compute_stsp(
|
438
|
+
self.__indptr,
|
439
|
+
self.__indices,
|
440
|
+
self.__edge_weights,
|
441
|
+
vertex_new,
|
442
|
+
self._n_vertices,
|
443
|
+
heap_length,
|
444
|
+
)
|
445
|
+
else:
|
446
|
+
path_length_values = compute_sssp(
|
447
|
+
self.__indptr,
|
448
|
+
self.__indices,
|
449
|
+
self.__edge_weights,
|
450
|
+
vertex_new,
|
451
|
+
self._n_vertices,
|
452
|
+
heap_length,
|
453
|
+
)
|
379
454
|
else:
|
380
455
|
self._path_links = np.arange(0, self._n_vertices, dtype=np.uint32)
|
381
|
-
if
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
456
|
+
if termination_nodes_array is not None:
|
457
|
+
# use early termination algorithms with path tracking
|
458
|
+
if self._orientation == "in":
|
459
|
+
path_length_values = compute_stsp_w_path_early_termination(
|
460
|
+
self.__indptr,
|
461
|
+
self.__indices,
|
462
|
+
self.__edge_weights,
|
463
|
+
self._path_links,
|
464
|
+
termination_nodes_array,
|
465
|
+
vertex_new,
|
466
|
+
self._n_vertices,
|
467
|
+
heap_length,
|
468
|
+
)
|
469
|
+
else:
|
470
|
+
path_length_values = compute_sssp_w_path_early_termination(
|
471
|
+
self.__indptr,
|
472
|
+
self.__indices,
|
473
|
+
self.__edge_weights,
|
474
|
+
self._path_links,
|
475
|
+
termination_nodes_array,
|
476
|
+
vertex_new,
|
477
|
+
self._n_vertices,
|
478
|
+
heap_length,
|
479
|
+
)
|
391
480
|
else:
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
481
|
+
# use standard algorithms with path tracking
|
482
|
+
if self._orientation == "in":
|
483
|
+
path_length_values = compute_stsp_w_path(
|
484
|
+
self.__indptr,
|
485
|
+
self.__indices,
|
486
|
+
self.__edge_weights,
|
487
|
+
self._path_links,
|
488
|
+
vertex_new,
|
489
|
+
self._n_vertices,
|
490
|
+
heap_length,
|
491
|
+
)
|
492
|
+
else:
|
493
|
+
path_length_values = compute_sssp_w_path(
|
494
|
+
self.__indptr,
|
495
|
+
self.__indices,
|
496
|
+
self.__edge_weights,
|
497
|
+
self._path_links,
|
498
|
+
vertex_new,
|
499
|
+
self._n_vertices,
|
500
|
+
heap_length,
|
501
|
+
)
|
401
502
|
|
402
503
|
if self._permute:
|
403
504
|
# permute back the path vertex indices
|
@@ -445,7 +546,7 @@ class Dijkstra:
|
|
445
546
|
|
446
547
|
# reorder path lengths
|
447
548
|
if return_series:
|
448
|
-
if self._permute:
|
549
|
+
if self._permute and termination_nodes_array is None:
|
449
550
|
self._permutation["path_length"] = path_length_values
|
450
551
|
path_lengths_df = self._permutation[
|
451
552
|
["vert_idx_old", "path_length"]
|
@@ -457,9 +558,16 @@ class Dijkstra:
|
|
457
558
|
path_lengths_series = pd.Series(path_length_values)
|
458
559
|
path_lengths_series.index.name = "vertex_idx"
|
459
560
|
path_lengths_series.name = "path_length"
|
561
|
+
if self._permute and termination_nodes_array is not None:
|
562
|
+
# For early termination with permutation, use original termination node indices
|
563
|
+
path_lengths_series.index = termination_nodes
|
460
564
|
|
461
565
|
return path_lengths_series
|
462
566
|
|
567
|
+
# For early termination, return results directly (already in correct order)
|
568
|
+
if termination_nodes_array is not None:
|
569
|
+
return path_length_values
|
570
|
+
|
463
571
|
if self._permute:
|
464
572
|
self._permutation["path_length"] = path_length_values
|
465
573
|
if return_inf:
|