@graphty/algorithms 2.1.1 → 2.2.0
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.
- package/README.md +139 -50
- package/dist/algorithms.js +15260 -10390
- package/dist/algorithms.js.map +1 -1
- package/dist/algorithms.standalone.js +26675 -21542
- package/dist/algorithms.standalone.js.map +1 -1
- package/dist/src/algorithms/centrality/betweenness.d.ts +18 -0
- package/dist/src/algorithms/centrality/betweenness.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/betweenness.js +40 -1
- package/dist/src/algorithms/centrality/betweenness.js.map +1 -1
- package/dist/src/algorithms/centrality/closeness.d.ts +20 -0
- package/dist/src/algorithms/centrality/closeness.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/closeness.js +93 -8
- package/dist/src/algorithms/centrality/closeness.js.map +1 -1
- package/dist/src/algorithms/centrality/degree.d.ts +9 -0
- package/dist/src/algorithms/centrality/degree.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/degree.js +18 -0
- package/dist/src/algorithms/centrality/degree.js.map +1 -1
- package/dist/src/algorithms/centrality/eigenvector.d.ts +10 -0
- package/dist/src/algorithms/centrality/eigenvector.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/eigenvector.js +29 -0
- package/dist/src/algorithms/centrality/eigenvector.js.map +1 -1
- package/dist/src/algorithms/centrality/hits.d.ts +9 -0
- package/dist/src/algorithms/centrality/hits.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/hits.js +23 -0
- package/dist/src/algorithms/centrality/hits.js.map +1 -1
- package/dist/src/algorithms/centrality/katz.d.ts +9 -0
- package/dist/src/algorithms/centrality/katz.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/katz.js +31 -0
- package/dist/src/algorithms/centrality/katz.js.map +1 -1
- package/dist/src/algorithms/centrality/pagerank.d.ts +13 -13
- package/dist/src/algorithms/centrality/pagerank.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/pagerank.js +47 -10
- package/dist/src/algorithms/centrality/pagerank.js.map +1 -1
- package/dist/src/algorithms/community/girvan-newman-legacy.d.ts +27 -0
- package/dist/src/algorithms/community/girvan-newman-legacy.d.ts.map +1 -0
- package/dist/src/algorithms/community/girvan-newman-legacy.js +335 -0
- package/dist/src/algorithms/community/girvan-newman-legacy.js.map +1 -0
- package/dist/src/algorithms/community/girvan-newman.d.ts +5 -3
- package/dist/src/algorithms/community/girvan-newman.d.ts.map +1 -1
- package/dist/src/algorithms/community/girvan-newman.js +34 -308
- package/dist/src/algorithms/community/girvan-newman.js.map +1 -1
- package/dist/src/algorithms/community/label-propagation.d.ts +9 -6
- package/dist/src/algorithms/community/label-propagation.d.ts.map +1 -1
- package/dist/src/algorithms/community/label-propagation.js +24 -110
- package/dist/src/algorithms/community/label-propagation.js.map +1 -1
- package/dist/src/algorithms/components/connected.d.ts.map +1 -1
- package/dist/src/algorithms/components/connected.js +28 -77
- package/dist/src/algorithms/components/connected.js.map +1 -1
- package/dist/src/algorithms/mst/kruskal.d.ts.map +1 -1
- package/dist/src/algorithms/mst/kruskal.js +59 -3
- package/dist/src/algorithms/mst/kruskal.js.map +1 -1
- package/dist/src/algorithms/shortest-path/bellman-ford.d.ts.map +1 -1
- package/dist/src/algorithms/shortest-path/bellman-ford.js +46 -0
- package/dist/src/algorithms/shortest-path/bellman-ford.js.map +1 -1
- package/dist/src/algorithms/shortest-path/dijkstra.d.ts.map +1 -1
- package/dist/src/algorithms/shortest-path/dijkstra.js +27 -0
- package/dist/src/algorithms/shortest-path/dijkstra.js.map +1 -1
- package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts +15 -5
- package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts.map +1 -1
- package/dist/src/algorithms/shortest-path/floyd-warshall.js +97 -107
- package/dist/src/algorithms/shortest-path/floyd-warshall.js.map +1 -1
- package/dist/src/algorithms/traversal/bfs-unified.d.ts +2 -12
- package/dist/src/algorithms/traversal/bfs-unified.d.ts.map +1 -1
- package/dist/src/algorithms/traversal/bfs-unified.js +47 -308
- package/dist/src/algorithms/traversal/bfs-unified.js.map +1 -1
- package/dist/src/algorithms/traversal/bfs-variants.d.ts.map +1 -1
- package/dist/src/algorithms/traversal/bfs-variants.js +5 -25
- package/dist/src/algorithms/traversal/bfs-variants.js.map +1 -1
- package/dist/src/algorithms/traversal/bfs.d.ts +0 -3
- package/dist/src/algorithms/traversal/bfs.d.ts.map +1 -1
- package/dist/src/algorithms/traversal/bfs.js +0 -4
- package/dist/src/algorithms/traversal/bfs.js.map +1 -1
- package/dist/src/algorithms/traversal/dfs.d.ts.map +1 -1
- package/dist/src/algorithms/traversal/dfs.js +33 -154
- package/dist/src/algorithms/traversal/dfs.js.map +1 -1
- package/dist/src/clustering/hierarchical-legacy.d.ts +56 -0
- package/dist/src/clustering/hierarchical-legacy.d.ts.map +1 -0
- package/dist/src/clustering/hierarchical-legacy.js +441 -0
- package/dist/src/clustering/hierarchical-legacy.js.map +1 -0
- package/dist/src/clustering/hierarchical.d.ts +7 -39
- package/dist/src/clustering/hierarchical.d.ts.map +1 -1
- package/dist/src/clustering/hierarchical.js +56 -417
- package/dist/src/clustering/hierarchical.js.map +1 -1
- package/dist/src/clustering/k-core-legacy.d.ts +30 -0
- package/dist/src/clustering/k-core-legacy.d.ts.map +1 -0
- package/dist/src/clustering/k-core-legacy.js +191 -0
- package/dist/src/clustering/k-core-legacy.js.map +1 -0
- package/dist/src/clustering/k-core.d.ts +8 -7
- package/dist/src/clustering/k-core.d.ts.map +1 -1
- package/dist/src/clustering/k-core.js +33 -174
- package/dist/src/clustering/k-core.js.map +1 -1
- package/dist/src/clustering/mcl-legacy.d.ts +42 -0
- package/dist/src/clustering/mcl-legacy.d.ts.map +1 -0
- package/dist/src/clustering/mcl-legacy.js +386 -0
- package/dist/src/clustering/mcl-legacy.js.map +1 -0
- package/dist/src/clustering/mcl.d.ts +9 -32
- package/dist/src/clustering/mcl.d.ts.map +1 -1
- package/dist/src/clustering/mcl.js +48 -374
- package/dist/src/clustering/mcl.js.map +1 -1
- package/dist/src/index.d.ts +29 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/indexed/accelerator.d.ts +141 -11
- package/dist/src/indexed/accelerator.d.ts.map +1 -1
- package/dist/src/indexed/accelerator.js +319 -5
- package/dist/src/indexed/accelerator.js.map +1 -1
- package/dist/src/indexed/all-pairs.d.ts +59 -0
- package/dist/src/indexed/all-pairs.d.ts.map +1 -0
- package/dist/src/indexed/all-pairs.js +274 -0
- package/dist/src/indexed/all-pairs.js.map +1 -0
- package/dist/src/indexed/bellman-ford.d.ts +25 -0
- package/dist/src/indexed/bellman-ford.d.ts.map +1 -0
- package/dist/src/indexed/bellman-ford.js +59 -0
- package/dist/src/indexed/bellman-ford.js.map +1 -0
- package/dist/src/indexed/betweenness.d.ts +85 -0
- package/dist/src/indexed/betweenness.d.ts.map +1 -0
- package/dist/src/indexed/betweenness.js +188 -0
- package/dist/src/indexed/betweenness.js.map +1 -0
- package/dist/src/indexed/bfs.d.ts +69 -2
- package/dist/src/indexed/bfs.d.ts.map +1 -1
- package/dist/src/indexed/bfs.js +148 -1
- package/dist/src/indexed/bfs.js.map +1 -1
- package/dist/src/indexed/bipartite.d.ts +37 -0
- package/dist/src/indexed/bipartite.d.ts.map +1 -0
- package/dist/src/indexed/bipartite.js +54 -0
- package/dist/src/indexed/bipartite.js.map +1 -0
- package/dist/src/indexed/closeness.d.ts +49 -0
- package/dist/src/indexed/closeness.d.ts.map +1 -0
- package/dist/src/indexed/closeness.js +127 -0
- package/dist/src/indexed/closeness.js.map +1 -0
- package/dist/src/indexed/common-neighbors.d.ts +14 -1
- package/dist/src/indexed/common-neighbors.d.ts.map +1 -1
- package/dist/src/indexed/common-neighbors.js +24 -14
- package/dist/src/indexed/common-neighbors.js.map +1 -1
- package/dist/src/indexed/degree.d.ts +19 -0
- package/dist/src/indexed/degree.d.ts.map +1 -0
- package/dist/src/indexed/degree.js +45 -0
- package/dist/src/indexed/degree.js.map +1 -0
- package/dist/src/indexed/delta-pagerank.d.ts +145 -0
- package/dist/src/indexed/delta-pagerank.d.ts.map +1 -0
- package/dist/src/indexed/delta-pagerank.js +428 -0
- package/dist/src/indexed/delta-pagerank.js.map +1 -0
- package/dist/src/indexed/dfs.d.ts +55 -0
- package/dist/src/indexed/dfs.d.ts.map +1 -0
- package/dist/src/indexed/dfs.js +146 -0
- package/dist/src/indexed/dfs.js.map +1 -0
- package/dist/src/indexed/eigenvector.d.ts +48 -0
- package/dist/src/indexed/eigenvector.d.ts.map +1 -0
- package/dist/src/indexed/eigenvector.js +162 -0
- package/dist/src/indexed/eigenvector.js.map +1 -0
- package/dist/src/indexed/facade.d.ts +109 -0
- package/dist/src/indexed/facade.d.ts.map +1 -0
- package/dist/src/indexed/facade.js +204 -0
- package/dist/src/indexed/facade.js.map +1 -0
- package/dist/src/indexed/flow.d.ts +120 -0
- package/dist/src/indexed/flow.d.ts.map +1 -0
- package/dist/src/indexed/flow.js +377 -0
- package/dist/src/indexed/flow.js.map +1 -0
- package/dist/src/indexed/girvan-newman.d.ts +42 -0
- package/dist/src/indexed/girvan-newman.d.ts.map +1 -0
- package/dist/src/indexed/girvan-newman.js +90 -0
- package/dist/src/indexed/girvan-newman.js.map +1 -0
- package/dist/src/indexed/grsbm.d.ts +85 -0
- package/dist/src/indexed/grsbm.d.ts.map +1 -0
- package/dist/src/indexed/grsbm.js +287 -0
- package/dist/src/indexed/grsbm.js.map +1 -0
- package/dist/src/indexed/hierarchical.d.ts +69 -0
- package/dist/src/indexed/hierarchical.d.ts.map +1 -0
- package/dist/src/indexed/hierarchical.js +245 -0
- package/dist/src/indexed/hierarchical.js.map +1 -0
- package/dist/src/indexed/index.d.ts +29 -3
- package/dist/src/indexed/index.d.ts.map +1 -1
- package/dist/src/indexed/index.js +29 -3
- package/dist/src/indexed/index.js.map +1 -1
- package/dist/src/indexed/isomorphism.d.ts +42 -0
- package/dist/src/indexed/isomorphism.d.ts.map +1 -0
- package/dist/src/indexed/isomorphism.js +269 -0
- package/dist/src/indexed/isomorphism.js.map +1 -0
- package/dist/src/indexed/label-propagation.d.ts +134 -0
- package/dist/src/indexed/label-propagation.d.ts.map +1 -0
- package/dist/src/indexed/label-propagation.js +486 -0
- package/dist/src/indexed/label-propagation.js.map +1 -0
- package/dist/src/indexed/leiden.d.ts +52 -0
- package/dist/src/indexed/leiden.d.ts.map +1 -0
- package/dist/src/indexed/leiden.js +384 -0
- package/dist/src/indexed/leiden.js.map +1 -0
- package/dist/src/indexed/link-prediction.d.ts +147 -0
- package/dist/src/indexed/link-prediction.d.ts.map +1 -0
- package/dist/src/indexed/link-prediction.js +317 -0
- package/dist/src/indexed/link-prediction.js.map +1 -0
- package/dist/src/indexed/markov.d.ts +54 -0
- package/dist/src/indexed/markov.d.ts.map +1 -0
- package/dist/src/indexed/markov.js +284 -0
- package/dist/src/indexed/markov.js.map +1 -0
- package/dist/src/indexed/matching.d.ts +53 -0
- package/dist/src/indexed/matching.d.ts.map +1 -0
- package/dist/src/indexed/matching.js +139 -0
- package/dist/src/indexed/matching.js.map +1 -0
- package/dist/src/indexed/min-cut.d.ts +48 -0
- package/dist/src/indexed/min-cut.d.ts.map +1 -0
- package/dist/src/indexed/min-cut.js +175 -0
- package/dist/src/indexed/min-cut.js.map +1 -0
- package/dist/src/indexed/modularity.d.ts +34 -0
- package/dist/src/indexed/modularity.d.ts.map +1 -0
- package/dist/src/indexed/modularity.js +74 -0
- package/dist/src/indexed/modularity.js.map +1 -0
- package/dist/src/indexed/mst.d.ts +29 -1
- package/dist/src/indexed/mst.d.ts.map +1 -1
- package/dist/src/indexed/mst.js +62 -0
- package/dist/src/indexed/mst.js.map +1 -1
- package/dist/src/indexed/pagerank.d.ts +29 -6
- package/dist/src/indexed/pagerank.d.ts.map +1 -1
- package/dist/src/indexed/pagerank.js +107 -11
- package/dist/src/indexed/pagerank.js.map +1 -1
- package/dist/src/indexed/point-to-point.d.ts +53 -0
- package/dist/src/indexed/point-to-point.d.ts.map +1 -0
- package/dist/src/indexed/point-to-point.js +173 -0
- package/dist/src/indexed/point-to-point.js.map +1 -0
- package/dist/src/indexed/scc.d.ts +53 -0
- package/dist/src/indexed/scc.d.ts.map +1 -0
- package/dist/src/indexed/scc.js +110 -0
- package/dist/src/indexed/scc.js.map +1 -0
- package/dist/src/indexed/spectral.d.ts +61 -0
- package/dist/src/indexed/spectral.d.ts.map +1 -0
- package/dist/src/indexed/spectral.js +476 -0
- package/dist/src/indexed/spectral.js.map +1 -0
- package/dist/src/indexed/structures/bit-set.d.ts +45 -0
- package/dist/src/indexed/structures/bit-set.d.ts.map +1 -0
- package/dist/src/indexed/structures/bit-set.js +57 -0
- package/dist/src/indexed/structures/bit-set.js.map +1 -0
- package/dist/src/indexed/structures/max-heap.d.ts +52 -0
- package/dist/src/indexed/structures/max-heap.d.ts.map +1 -0
- package/dist/src/indexed/structures/max-heap.js +66 -0
- package/dist/src/indexed/structures/max-heap.js.map +1 -0
- package/dist/src/indexed/structures/min-heap.d.ts +30 -1
- package/dist/src/indexed/structures/min-heap.d.ts.map +1 -1
- package/dist/src/indexed/structures/min-heap.js +46 -6
- package/dist/src/indexed/structures/min-heap.js.map +1 -1
- package/dist/src/indexed/structures/ring-queue.d.ts +41 -0
- package/dist/src/indexed/structures/ring-queue.d.ts.map +1 -0
- package/dist/src/indexed/structures/ring-queue.js +64 -0
- package/dist/src/indexed/structures/ring-queue.js.map +1 -0
- package/dist/src/indexed/sync.d.ts +50 -0
- package/dist/src/indexed/sync.d.ts.map +1 -0
- package/dist/src/indexed/sync.js +175 -0
- package/dist/src/indexed/sync.js.map +1 -0
- package/dist/src/indexed/terahac.d.ts +58 -0
- package/dist/src/indexed/terahac.d.ts.map +1 -0
- package/dist/src/indexed/terahac.js +244 -0
- package/dist/src/indexed/terahac.js.map +1 -0
- package/dist/src/indexed/to-snapshot.d.ts +45 -2
- package/dist/src/indexed/to-snapshot.d.ts.map +1 -1
- package/dist/src/indexed/to-snapshot.js +140 -6
- package/dist/src/indexed/to-snapshot.js.map +1 -1
- package/dist/src/link-prediction/common-neighbors-legacy.d.ts +71 -0
- package/dist/src/link-prediction/common-neighbors-legacy.d.ts.map +1 -0
- package/dist/src/link-prediction/common-neighbors-legacy.js +172 -0
- package/dist/src/link-prediction/common-neighbors-legacy.js.map +1 -0
- package/dist/src/link-prediction/common-neighbors.d.ts +11 -19
- package/dist/src/link-prediction/common-neighbors.d.ts.map +1 -1
- package/dist/src/link-prediction/common-neighbors.js +56 -123
- package/dist/src/link-prediction/common-neighbors.js.map +1 -1
- package/dist/src/optimized/direction-optimized-bfs.d.ts +6 -0
- package/dist/src/optimized/direction-optimized-bfs.d.ts.map +1 -1
- package/dist/src/optimized/direction-optimized-bfs.js +6 -0
- package/dist/src/optimized/direction-optimized-bfs.js.map +1 -1
- package/dist/src/research/grsbm-legacy.d.ts +82 -0
- package/dist/src/research/grsbm-legacy.d.ts.map +1 -0
- package/dist/src/research/grsbm-legacy.js +416 -0
- package/dist/src/research/grsbm-legacy.js.map +1 -0
- package/dist/src/research/grsbm.d.ts +9 -66
- package/dist/src/research/grsbm.d.ts.map +1 -1
- package/dist/src/research/grsbm.js +67 -391
- package/dist/src/research/grsbm.js.map +1 -1
- package/dist/src/research/sync-legacy.d.ts +48 -0
- package/dist/src/research/sync-legacy.d.ts.map +1 -0
- package/dist/src/research/sync-legacy.js +337 -0
- package/dist/src/research/sync-legacy.js.map +1 -0
- package/dist/src/research/sync.d.ts +10 -32
- package/dist/src/research/sync.d.ts.map +1 -1
- package/dist/src/research/sync.js +28 -316
- package/dist/src/research/sync.js.map +1 -1
- package/package.json +4 -3
- package/src/algorithms/centrality/betweenness.ts +51 -1
- package/src/algorithms/centrality/closeness.ts +112 -12
- package/src/algorithms/centrality/degree.ts +19 -0
- package/src/algorithms/centrality/eigenvector.ts +34 -0
- package/src/algorithms/centrality/hits.ts +24 -0
- package/src/algorithms/centrality/katz.ts +32 -0
- package/src/algorithms/centrality/pagerank.ts +53 -13
- package/src/algorithms/community/girvan-newman-legacy.ts +414 -0
- package/src/algorithms/community/girvan-newman.ts +36 -386
- package/src/algorithms/community/label-propagation.ts +24 -133
- package/src/algorithms/components/connected.ts +28 -95
- package/src/algorithms/mst/kruskal.ts +65 -4
- package/src/algorithms/shortest-path/bellman-ford.ts +49 -0
- package/src/algorithms/shortest-path/dijkstra.ts +29 -0
- package/src/algorithms/shortest-path/floyd-warshall.ts +106 -136
- package/src/algorithms/traversal/bfs-unified.ts +52 -366
- package/src/algorithms/traversal/bfs-variants.ts +5 -28
- package/src/algorithms/traversal/bfs.ts +0 -4
- package/src/algorithms/traversal/dfs.ts +39 -182
- package/src/clustering/hierarchical-legacy.ts +551 -0
- package/src/clustering/hierarchical.ts +64 -520
- package/src/clustering/k-core-legacy.ts +229 -0
- package/src/clustering/k-core.ts +38 -209
- package/src/clustering/mcl-legacy.ts +498 -0
- package/src/clustering/mcl.ts +46 -479
- package/src/index.ts +90 -3
- package/src/indexed/accelerator.ts +502 -16
- package/src/indexed/all-pairs.ts +342 -0
- package/src/indexed/bellman-ford.ts +72 -0
- package/src/indexed/betweenness.ts +258 -0
- package/src/indexed/bfs.ts +189 -3
- package/src/indexed/bipartite.ts +77 -0
- package/src/indexed/closeness.ts +160 -0
- package/src/indexed/common-neighbors.ts +31 -14
- package/src/indexed/degree.ts +55 -0
- package/src/indexed/delta-pagerank.ts +513 -0
- package/src/indexed/dfs.ts +189 -0
- package/src/indexed/eigenvector.ts +202 -0
- package/src/indexed/facade.ts +229 -0
- package/src/indexed/flow.ts +500 -0
- package/src/indexed/girvan-newman.ts +120 -0
- package/src/indexed/grsbm.ts +390 -0
- package/src/indexed/hierarchical.ts +295 -0
- package/src/indexed/index.ts +94 -3
- package/src/indexed/isomorphism.ts +305 -0
- package/src/indexed/label-propagation.ts +582 -0
- package/src/indexed/leiden.ts +436 -0
- package/src/indexed/link-prediction.ts +399 -0
- package/src/indexed/markov.ts +324 -0
- package/src/indexed/matching.ts +192 -0
- package/src/indexed/min-cut.ts +201 -0
- package/src/indexed/modularity.ts +81 -0
- package/src/indexed/mst.ts +79 -1
- package/src/indexed/pagerank.ts +128 -15
- package/src/indexed/point-to-point.ts +220 -0
- package/src/indexed/scc.ts +132 -0
- package/src/indexed/spectral.ts +550 -0
- package/src/indexed/structures/bit-set.ts +65 -0
- package/src/indexed/structures/max-heap.ts +74 -0
- package/src/indexed/structures/min-heap.ts +51 -6
- package/src/indexed/structures/ring-queue.ts +70 -0
- package/src/indexed/sync.ts +229 -0
- package/src/indexed/terahac.ts +290 -0
- package/src/indexed/to-snapshot.ts +156 -6
- package/src/link-prediction/common-neighbors-legacy.ts +252 -0
- package/src/link-prediction/common-neighbors.ts +65 -168
- package/src/optimized/direction-optimized-bfs.ts +6 -1
- package/src/research/grsbm-legacy.ts +586 -0
- package/src/research/grsbm.ts +76 -555
- package/src/research/sync-legacy.ts +456 -0
- package/src/research/sync.ts +30 -431
|
@@ -1,43 +1,39 @@
|
|
|
1
|
+
import { type GraphSnapshot, INVALID_INDEX } from "@graphty/graph-format";
|
|
2
|
+
|
|
1
3
|
import type { Graph } from "../../core/graph.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
4
|
+
import { type BfsResult, breadthFirstSearch as indexedBreadthFirstSearch } from "../../indexed/bfs.js";
|
|
5
|
+
import { isBipartite as indexedIsBipartite } from "../../indexed/bipartite.js";
|
|
6
|
+
import { orderToTree } from "../../indexed/facade.js";
|
|
7
|
+
import { legacyArcOrder, toTopologySnapshot } from "../../indexed/to-snapshot.js";
|
|
5
8
|
import type { NodeId, ShortestPathResult, TraversalOptions, TraversalResult } from "../../types/index.js";
|
|
6
9
|
import { reconstructPath } from "../../utils/graph-utilities.js";
|
|
7
10
|
|
|
8
11
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* -
|
|
15
|
-
*
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
// Cache for CSR conversions to avoid repeated conversions
|
|
19
|
-
const csrCache = new WeakMap<Graph, CSRGraph>();
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Get or create CSR representation of a graph
|
|
23
|
-
* @param graph - The input graph to convert
|
|
24
|
-
* @returns CSR graph representation (cached for efficiency)
|
|
12
|
+
* Breadth-first search, run by `indexed.breadthFirstSearch` over the graph's snapshot with each
|
|
13
|
+
* node's neighbours tried in the graph's insertion order, so every graph, of any size, gets the
|
|
14
|
+
* visit order, tree and depths the standard queue walk gives.
|
|
15
|
+
* @param graph - The input graph
|
|
16
|
+
* @param startNode - The start node
|
|
17
|
+
* @param targetNode - Stop once this node is taken off the queue; ignored when it is not a node
|
|
18
|
+
* @returns The snapshot, the port's result and the target's index (INVALID_INDEX for none)
|
|
25
19
|
*/
|
|
26
|
-
function
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
20
|
+
function search(
|
|
21
|
+
graph: Graph,
|
|
22
|
+
startNode: NodeId,
|
|
23
|
+
targetNode?: NodeId,
|
|
24
|
+
): { s: GraphSnapshot; result: BfsResult; target: number } {
|
|
25
|
+
const s = toTopologySnapshot(graph);
|
|
26
|
+
const start = s.ids.indexOf(startNode);
|
|
27
|
+
const target = targetNode === undefined ? INVALID_INDEX : s.ids.indexOf(targetNode);
|
|
28
|
+
const result = indexedBreadthFirstSearch(s, start, {
|
|
29
|
+
arcOrder: legacyArcOrder(graph, s),
|
|
30
|
+
target: target === INVALID_INDEX ? undefined : target,
|
|
31
|
+
});
|
|
32
|
+
return { s, result, target };
|
|
34
33
|
}
|
|
35
34
|
|
|
36
35
|
/**
|
|
37
36
|
* Perform breadth-first search starting from a given node
|
|
38
|
-
*
|
|
39
|
-
* Automatically uses the most optimized implementation based on graph size.
|
|
40
|
-
* No configuration needed - just call this function for the best performance.
|
|
41
37
|
* @param graph - The input graph to traverse
|
|
42
38
|
* @param startNode - The node to start the BFS from
|
|
43
39
|
* @param options - Traversal options (callbacks, target node, etc.)
|
|
@@ -47,125 +43,23 @@ export function breadthFirstSearch(graph: Graph, startNode: NodeId, options: Tra
|
|
|
47
43
|
if (!graph.hasNode(startNode)) {
|
|
48
44
|
throw new Error(`Start node ${String(startNode)} not found in graph`);
|
|
49
45
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
* @param startNode - The node to start the BFS from
|
|
64
|
-
* @param options - Traversal options (callbacks, target node, etc.)
|
|
65
|
-
* @returns Traversal result with visited nodes, order, and tree structure
|
|
66
|
-
*/
|
|
67
|
-
function breadthFirstSearchStandard(graph: Graph, startNode: NodeId, options: TraversalOptions = {}): TraversalResult {
|
|
68
|
-
const visited = new Set<NodeId>();
|
|
69
|
-
const queue: { node: NodeId; level: number }[] = [];
|
|
70
|
-
const order: NodeId[] = [];
|
|
71
|
-
const tree = new Map<NodeId, NodeId | null>();
|
|
72
|
-
|
|
73
|
-
// Initialize with start node
|
|
74
|
-
queue.push({ node: startNode, level: 0 });
|
|
75
|
-
visited.add(startNode);
|
|
76
|
-
tree.set(startNode, null);
|
|
77
|
-
|
|
78
|
-
while (queue.length > 0) {
|
|
79
|
-
const current = queue.shift();
|
|
80
|
-
if (!current) {
|
|
81
|
-
break;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
order.push(current.node);
|
|
85
|
-
|
|
86
|
-
// Call visitor callback if provided
|
|
87
|
-
if (options.visitCallback) {
|
|
88
|
-
options.visitCallback(current.node, current.level);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Early termination if target found
|
|
92
|
-
if (options.targetNode !== undefined && current.node === options.targetNode) {
|
|
93
|
-
break;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Explore neighbors
|
|
97
|
-
for (const neighbor of graph.neighbors(current.node)) {
|
|
98
|
-
if (!visited.has(neighbor)) {
|
|
99
|
-
visited.add(neighbor);
|
|
100
|
-
tree.set(neighbor, current.node);
|
|
101
|
-
queue.push({ node: neighbor, level: current.level + 1 });
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
return { visited, order, tree };
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Optimized BFS implementation using Direction-Optimized BFS
|
|
111
|
-
* @param graph - The input graph to traverse
|
|
112
|
-
* @param startNode - The node to start the BFS from
|
|
113
|
-
* @param options - Traversal options (callbacks, target node, etc.)
|
|
114
|
-
* @returns Traversal result with visited nodes, order, and tree structure
|
|
115
|
-
*/
|
|
116
|
-
function breadthFirstSearchOptimized(graph: Graph, startNode: NodeId, options: TraversalOptions = {}): TraversalResult {
|
|
117
|
-
const csrGraph = getCSRGraph(graph);
|
|
118
|
-
|
|
119
|
-
const dobfs = new DirectionOptimizedBFS(csrGraph, {
|
|
120
|
-
alpha: 15.0,
|
|
121
|
-
beta: 20.0,
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
const result = dobfs.search(startNode);
|
|
125
|
-
|
|
126
|
-
// Convert result to TraversalResult format
|
|
127
|
-
const visited = new Set<NodeId>();
|
|
128
|
-
const order: NodeId[] = [];
|
|
129
|
-
const tree = new Map<NodeId, NodeId | null>();
|
|
130
|
-
|
|
131
|
-
// Build traversal order using BFS from distances
|
|
132
|
-
const nodesByDistance = new Map<number, NodeId[]>();
|
|
133
|
-
let maxDistance = 0;
|
|
134
|
-
|
|
135
|
-
for (const [nodeId, distance] of result.distances) {
|
|
136
|
-
visited.add(nodeId);
|
|
137
|
-
tree.set(nodeId, result.parents.get(nodeId) ?? null);
|
|
138
|
-
|
|
139
|
-
if (!nodesByDistance.has(distance)) {
|
|
140
|
-
nodesByDistance.set(distance, []);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
nodesByDistance.get(distance)?.push(nodeId);
|
|
144
|
-
maxDistance = Math.max(maxDistance, distance);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// Reconstruct BFS order
|
|
148
|
-
for (let d = 0; d <= maxDistance; d++) {
|
|
149
|
-
const nodes = nodesByDistance.get(d);
|
|
150
|
-
if (nodes) {
|
|
151
|
-
order.push(...nodes);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Handle visit callback if provided
|
|
156
|
-
if (options.visitCallback) {
|
|
157
|
-
for (const [nodeId, distance] of result.distances) {
|
|
158
|
-
options.visitCallback(nodeId, distance);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
return { visited, order, tree };
|
|
46
|
+
const { s, result, target } = search(graph, startNode, options.targetNode);
|
|
47
|
+
const { order, depth } = result;
|
|
48
|
+
const tree = orderToTree(s.ids, order, result.parent);
|
|
49
|
+
// `order` lists every node discovered; the walk expanded them up to and including the target.
|
|
50
|
+
const found = target === INVALID_INDEX ? -1 : order.indexOf(target);
|
|
51
|
+
const expanded = found === -1 ? order : order.subarray(0, found + 1);
|
|
52
|
+
const visitOrder: NodeId[] = [];
|
|
53
|
+
for (const i of expanded) {
|
|
54
|
+
const id = s.ids.idOf(i);
|
|
55
|
+
visitOrder.push(id);
|
|
56
|
+
options.visitCallback?.(id, depth[i]);
|
|
57
|
+
}
|
|
58
|
+
return { visited: new Set(tree.keys()), order: visitOrder, tree };
|
|
163
59
|
}
|
|
164
60
|
|
|
165
61
|
/**
|
|
166
62
|
* Find shortest path between two nodes using BFS
|
|
167
|
-
*
|
|
168
|
-
* Automatically optimized for large graphs. Returns null if no path exists.
|
|
169
63
|
* @param graph - The input graph to search
|
|
170
64
|
* @param source - The source node ID
|
|
171
65
|
* @param target - The target node ID
|
|
@@ -180,7 +74,6 @@ export function shortestPathBFS(graph: Graph, source: NodeId, target: NodeId): S
|
|
|
180
74
|
throw new Error(`Target node ${String(target)} not found in graph`);
|
|
181
75
|
}
|
|
182
76
|
|
|
183
|
-
// Special case: source equals target
|
|
184
77
|
if (source === target) {
|
|
185
78
|
return {
|
|
186
79
|
distance: 0,
|
|
@@ -189,206 +82,36 @@ export function shortestPathBFS(graph: Graph, source: NodeId, target: NodeId): S
|
|
|
189
82
|
};
|
|
190
83
|
}
|
|
191
84
|
|
|
192
|
-
|
|
193
|
-
if (
|
|
194
|
-
return
|
|
85
|
+
const { s, result, target: t } = search(graph, source, target);
|
|
86
|
+
if (result.depth[t] === INVALID_INDEX) {
|
|
87
|
+
return null;
|
|
195
88
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
return shortestPathBFSStandard(graph, source, target);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Standard shortest path BFS
|
|
203
|
-
* @param graph - The input graph to search
|
|
204
|
-
* @param source - The source node ID
|
|
205
|
-
* @param target - The target node ID
|
|
206
|
-
* @returns Shortest path result or null if no path exists
|
|
207
|
-
*/
|
|
208
|
-
function shortestPathBFSStandard(graph: Graph, source: NodeId, target: NodeId): ShortestPathResult | null {
|
|
209
|
-
const visited = new Set<NodeId>();
|
|
210
|
-
const queue: { node: NodeId; distance: number }[] = [];
|
|
211
|
-
const predecessor = new Map<NodeId, NodeId | null>();
|
|
212
|
-
|
|
213
|
-
// Initialize BFS
|
|
214
|
-
queue.push({ node: source, distance: 0 });
|
|
215
|
-
visited.add(source);
|
|
216
|
-
predecessor.set(source, null);
|
|
217
|
-
|
|
218
|
-
while (queue.length > 0) {
|
|
219
|
-
const current = queue.shift();
|
|
220
|
-
if (!current) {
|
|
221
|
-
break;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// Target found
|
|
225
|
-
if (current.node === target) {
|
|
226
|
-
const path = reconstructPath(target, predecessor);
|
|
227
|
-
return {
|
|
228
|
-
distance: current.distance,
|
|
229
|
-
path,
|
|
230
|
-
predecessor,
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
// Explore neighbors
|
|
235
|
-
for (const neighbor of graph.neighbors(current.node)) {
|
|
236
|
-
if (!visited.has(neighbor)) {
|
|
237
|
-
visited.add(neighbor);
|
|
238
|
-
predecessor.set(neighbor, current.node);
|
|
239
|
-
queue.push({ node: neighbor, distance: current.distance + 1 });
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// No path found
|
|
245
|
-
return null;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* Optimized shortest path using Direction-Optimized BFS
|
|
250
|
-
* @param graph - The input graph to search
|
|
251
|
-
* @param source - The source node ID
|
|
252
|
-
* @param target - The target node ID
|
|
253
|
-
* @returns Shortest path result or null if no path exists
|
|
254
|
-
*/
|
|
255
|
-
function shortestPathBFSOptimized(graph: Graph, source: NodeId, target: NodeId): ShortestPathResult | null {
|
|
256
|
-
const csrGraph = getCSRGraph(graph);
|
|
257
|
-
|
|
258
|
-
const dobfs = new DirectionOptimizedBFS(csrGraph, {
|
|
259
|
-
alpha: 15.0,
|
|
260
|
-
beta: 20.0,
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
// Perform BFS
|
|
264
|
-
const result = dobfs.search(source);
|
|
265
|
-
|
|
266
|
-
// Check if target was reached
|
|
267
|
-
const distance = result.distances.get(target);
|
|
268
|
-
if (distance === undefined) {
|
|
269
|
-
return null; // No path found
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// Reconstruct path
|
|
273
|
-
const path = reconstructPath(target, result.parents);
|
|
274
|
-
|
|
275
|
-
return {
|
|
276
|
-
distance,
|
|
277
|
-
path,
|
|
278
|
-
predecessor: result.parents,
|
|
279
|
-
};
|
|
89
|
+
const predecessor = orderToTree(s.ids, result.order, result.parent);
|
|
90
|
+
return { distance: result.depth[t], path: reconstructPath(target, predecessor), predecessor };
|
|
280
91
|
}
|
|
281
92
|
|
|
282
93
|
/**
|
|
283
94
|
* Find shortest paths from source to all reachable nodes
|
|
284
|
-
*
|
|
285
|
-
* Automatically optimized for large graphs.
|
|
286
95
|
* @param graph - The input graph to search
|
|
287
96
|
* @param source - The source node ID to compute shortest paths from
|
|
288
|
-
* @returns Map of node IDs to their shortest path results
|
|
97
|
+
* @returns Map of node IDs to their shortest path results, every entry sharing one predecessor map
|
|
289
98
|
*/
|
|
290
99
|
export function singleSourceShortestPathBFS(graph: Graph, source: NodeId): Map<NodeId, ShortestPathResult> {
|
|
291
100
|
if (!graph.hasNode(source)) {
|
|
292
101
|
throw new Error(`Source node ${String(source)} not found in graph`);
|
|
293
102
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
if (graph.nodeCount > 10000) {
|
|
297
|
-
return singleSourceShortestPathBFSOptimized(graph, source);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
// Standard implementation
|
|
301
|
-
return singleSourceShortestPathBFSStandard(graph, source);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/**
|
|
305
|
-
* Standard single-source shortest paths
|
|
306
|
-
* @param graph - The input graph to search
|
|
307
|
-
* @param source - The source node ID to compute shortest paths from
|
|
308
|
-
* @returns Map of node IDs to their shortest path results
|
|
309
|
-
*/
|
|
310
|
-
function singleSourceShortestPathBFSStandard(graph: Graph, source: NodeId): Map<NodeId, ShortestPathResult> {
|
|
311
|
-
const results = new Map<NodeId, ShortestPathResult>();
|
|
312
|
-
const visited = new Set<NodeId>();
|
|
313
|
-
const queue: { node: NodeId; distance: number }[] = [];
|
|
314
|
-
const predecessor = new Map<NodeId, NodeId | null>();
|
|
315
|
-
const distances = new Map<NodeId, number>();
|
|
316
|
-
|
|
317
|
-
// Initialize BFS
|
|
318
|
-
queue.push({ node: source, distance: 0 });
|
|
319
|
-
visited.add(source);
|
|
320
|
-
predecessor.set(source, null);
|
|
321
|
-
distances.set(source, 0);
|
|
322
|
-
|
|
323
|
-
while (queue.length > 0) {
|
|
324
|
-
const current = queue.shift();
|
|
325
|
-
if (!current) {
|
|
326
|
-
break;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// Explore neighbors
|
|
330
|
-
for (const neighbor of graph.neighbors(current.node)) {
|
|
331
|
-
if (!visited.has(neighbor)) {
|
|
332
|
-
visited.add(neighbor);
|
|
333
|
-
predecessor.set(neighbor, current.node);
|
|
334
|
-
distances.set(neighbor, current.distance + 1);
|
|
335
|
-
queue.push({ node: neighbor, distance: current.distance + 1 });
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
// Build results after BFS completes
|
|
341
|
-
// This avoids copying the predecessor map for each node
|
|
342
|
-
for (const [node, distance] of distances) {
|
|
343
|
-
const path = reconstructPath(node, predecessor);
|
|
344
|
-
results.set(node, {
|
|
345
|
-
distance,
|
|
346
|
-
path,
|
|
347
|
-
predecessor, // Share the same predecessor map
|
|
348
|
-
});
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
return results;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
/**
|
|
355
|
-
* Optimized single-source shortest paths
|
|
356
|
-
* @param graph - The input graph to search
|
|
357
|
-
* @param source - The source node ID to compute shortest paths from
|
|
358
|
-
* @returns Map of node IDs to their shortest path results
|
|
359
|
-
*/
|
|
360
|
-
function singleSourceShortestPathBFSOptimized(graph: Graph, source: NodeId): Map<NodeId, ShortestPathResult> {
|
|
361
|
-
const csrGraph = getCSRGraph(graph);
|
|
362
|
-
|
|
363
|
-
const dobfs = new DirectionOptimizedBFS(csrGraph, {
|
|
364
|
-
alpha: 15.0,
|
|
365
|
-
beta: 20.0,
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
const bfsResult = dobfs.search(source);
|
|
369
|
-
|
|
370
|
-
// Convert to expected format
|
|
103
|
+
const { s, result } = search(graph, source);
|
|
104
|
+
const predecessor = orderToTree(s.ids, result.order, result.parent);
|
|
371
105
|
const results = new Map<NodeId, ShortestPathResult>();
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
const path = reconstructPath(nodeId, bfsResult.parents);
|
|
376
|
-
|
|
377
|
-
results.set(nodeId, {
|
|
378
|
-
distance,
|
|
379
|
-
path,
|
|
380
|
-
predecessor: bfsResult.parents, // Share the same predecessor map
|
|
381
|
-
});
|
|
106
|
+
for (const i of result.order) {
|
|
107
|
+
const node = s.ids.idOf(i);
|
|
108
|
+
results.set(node, { distance: result.depth[i], path: reconstructPath(node, predecessor), predecessor });
|
|
382
109
|
}
|
|
383
|
-
|
|
384
110
|
return results;
|
|
385
111
|
}
|
|
386
112
|
|
|
387
113
|
/**
|
|
388
|
-
* Check if the graph is bipartite
|
|
389
|
-
*
|
|
390
|
-
* Note: This function does not use Direction-Optimized BFS as the
|
|
391
|
-
* coloring logic is specific and doesn't benefit from the optimization.
|
|
114
|
+
* Check if the graph is bipartite
|
|
392
115
|
* @param graph - The undirected graph to check
|
|
393
116
|
* @returns True if the graph is bipartite, false otherwise
|
|
394
117
|
*/
|
|
@@ -396,42 +119,5 @@ export function isBipartite(graph: Graph): boolean {
|
|
|
396
119
|
if (graph.isDirected) {
|
|
397
120
|
throw new Error("Bipartite test requires an undirected graph");
|
|
398
121
|
}
|
|
399
|
-
|
|
400
|
-
const color = new Map<NodeId, 0 | 1>();
|
|
401
|
-
const visited = new Set<NodeId>();
|
|
402
|
-
|
|
403
|
-
// Check each connected component
|
|
404
|
-
for (const node of Array.from(graph.nodes())) {
|
|
405
|
-
if (!visited.has(node.id)) {
|
|
406
|
-
const queue: NodeId[] = [node.id];
|
|
407
|
-
color.set(node.id, 0);
|
|
408
|
-
visited.add(node.id);
|
|
409
|
-
|
|
410
|
-
while (queue.length > 0) {
|
|
411
|
-
const current = queue.shift();
|
|
412
|
-
if (current === undefined) {
|
|
413
|
-
break;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
const currentColor = color.get(current);
|
|
417
|
-
if (currentColor === undefined) {
|
|
418
|
-
continue;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
for (const neighbor of Array.from(graph.neighbors(current))) {
|
|
422
|
-
if (!visited.has(neighbor)) {
|
|
423
|
-
// Color with opposite color
|
|
424
|
-
color.set(neighbor, currentColor === 0 ? 1 : 0);
|
|
425
|
-
visited.add(neighbor);
|
|
426
|
-
queue.push(neighbor);
|
|
427
|
-
} else if (color.get(neighbor) === currentColor) {
|
|
428
|
-
// Same color as current node - not bipartite
|
|
429
|
-
return false;
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
return true;
|
|
122
|
+
return indexedIsBipartite(toTopologySnapshot(graph)).bipartite;
|
|
437
123
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Graph } from "../../core/graph.js";
|
|
2
2
|
import { PriorityQueue } from "../../data-structures/priority-queue.js";
|
|
3
3
|
import { CSRGraph } from "../../optimized/csr-graph.js";
|
|
4
|
-
import { DirectionOptimizedBFS } from "../../optimized/direction-optimized-bfs.js";
|
|
5
4
|
import { toCSRGraph } from "../../optimized/graph-adapter.js";
|
|
6
5
|
import type { NodeId } from "../../types/index.js";
|
|
7
6
|
|
|
@@ -415,37 +414,15 @@ function bfsWithPathCountingCSR(
|
|
|
415
414
|
* @returns Map of node IDs to their shortest distances from the source
|
|
416
415
|
*/
|
|
417
416
|
function bfsDistancesOnlyCSR(graph: CSRGraph, source: NodeId, cutoff?: number): Map<NodeId, number> {
|
|
418
|
-
//
|
|
419
|
-
|
|
420
|
-
const dobfs = new DirectionOptimizedBFS(graph);
|
|
421
|
-
const result = dobfs.search(source);
|
|
422
|
-
|
|
423
|
-
// Filter by cutoff if specified
|
|
424
|
-
if (cutoff !== undefined) {
|
|
425
|
-
const filtered = new Map<NodeId, number>();
|
|
426
|
-
for (const [nodeId, distance] of result.distances) {
|
|
427
|
-
if (distance <= cutoff) {
|
|
428
|
-
filtered.set(nodeId, distance);
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
return filtered;
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
return result.distances;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
// Fallback to standard BFS on CSR
|
|
417
|
+
// Plain top-down BFS on CSR. The DirectionOptimizedBFS class is not used here: its 16-bit
|
|
418
|
+
// distances throw once a path passes 65,534 hops.
|
|
438
419
|
const distances = new Map<NodeId, number>();
|
|
439
|
-
const queue: NodeId[] = [];
|
|
420
|
+
const queue: NodeId[] = [source];
|
|
440
421
|
|
|
441
422
|
distances.set(source, 0);
|
|
442
|
-
queue.push(source);
|
|
443
423
|
|
|
444
|
-
|
|
445
|
-
const current = queue
|
|
446
|
-
if (current === undefined) {
|
|
447
|
-
continue;
|
|
448
|
-
}
|
|
424
|
+
for (let head = 0; head < queue.length; head++) {
|
|
425
|
+
const current = queue[head];
|
|
449
426
|
|
|
450
427
|
const currentDistance = distances.get(current) ?? 0;
|
|
451
428
|
|
|
@@ -3,10 +3,6 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Explores graph level by level from a starting node. Guarantees shortest path
|
|
5
5
|
* in unweighted graphs and can be used for various graph analysis tasks.
|
|
6
|
-
*
|
|
7
|
-
* Automatically uses optimized implementations for large graphs (>10k nodes)
|
|
8
|
-
* to provide the best performance without requiring manual configuration.
|
|
9
6
|
*/
|
|
10
7
|
|
|
11
|
-
// Re-export unified implementations that automatically optimize for large graphs
|
|
12
8
|
export { breadthFirstSearch, isBipartite, shortestPathBFS, singleSourceShortestPathBFS } from "./bfs-unified.js";
|