@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
package/README.md
CHANGED
|
@@ -23,39 +23,24 @@ A comprehensive TypeScript graph algorithms library with 98 algorithms optimized
|
|
|
23
23
|
|
|
24
24
|
## Performance Optimizations
|
|
25
25
|
|
|
26
|
-
The
|
|
26
|
+
The graph functions (`breadthFirstSearch`, `shortestPathBFS`, `connectedComponents`, `kruskalMST`
|
|
27
|
+
and others) run over a compact indexed snapshot of the graph, with typed arrays in Compressed Sparse
|
|
28
|
+
Row form, and return the same results they always have.
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
- **Bit-Packed Data Structures**: 8x memory reduction using bit arrays for boolean data
|
|
31
|
-
|
|
32
|
-
These optimizations are applied automatically - no configuration needed! Just use the standard API:
|
|
30
|
+
For very large graphs, the direction-optimising BFS is available explicitly over a snapshot. It
|
|
31
|
+
switches between top-down and bottom-up steps, which is fastest on large low-diameter graphs:
|
|
33
32
|
|
|
34
33
|
```typescript
|
|
35
|
-
|
|
36
|
-
const result = breadthFirstSearch(largeGraph, startNode);
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
All BFS-based algorithms benefit from these optimizations:
|
|
40
|
-
|
|
41
|
-
- `breadthFirstSearch`, `shortestPathBFS`, `singleSourceShortestPathBFS`
|
|
42
|
-
- `betweennessCentrality`, `closenessCentrality`
|
|
43
|
-
- Connected component algorithms
|
|
44
|
-
|
|
45
|
-
### Performance Benchmarks
|
|
34
|
+
import { indexed, toSnapshot } from "@graphty/algorithms";
|
|
46
35
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
| 50K nodes | 158.64ms | 44.27ms | 3.58x |
|
|
51
|
-
| 100K nodes | 5,370ms | 126ms | 42.58x |
|
|
52
|
-
|
|
53
|
-
_Note: Optimizations activate automatically for graphs ≥10K nodes to avoid conversion overhead on smaller graphs._
|
|
36
|
+
const s = toSnapshot(largeGraph);
|
|
37
|
+
const { order, parent, depth } = indexed.directionOptimizedBfs(s, s.ids.requireIndex(startNode));
|
|
38
|
+
```
|
|
54
39
|
|
|
55
40
|
### Learn More
|
|
56
41
|
|
|
57
|
-
-
|
|
58
|
-
-
|
|
42
|
+
- [Performance Guide](docs/guide/performance.md) - Detailed optimization explanations
|
|
43
|
+
- [Memory](docs/guide/performance.md#memory) - What a snapshot costs
|
|
59
44
|
|
|
60
45
|
## Installation
|
|
61
46
|
|
|
@@ -65,34 +50,38 @@ npm install @graphty/algorithms
|
|
|
65
50
|
|
|
66
51
|
## Quick Start
|
|
67
52
|
|
|
68
|
-
|
|
69
|
-
|
|
53
|
+
Algorithms run over a frozen graph snapshot from [`@graphty/graph-format`](https://www.npmjs.com/package/@graphty/graph-format)
|
|
54
|
+
and are reached through the `indexed` namespace. Each takes the snapshot first and an options object last, works on
|
|
55
|
+
node indices, and returns typed arrays indexed by node:
|
|
70
56
|
|
|
71
|
-
|
|
72
|
-
const graph = new Graph();
|
|
57
|
+
<!-- doc-check -->
|
|
73
58
|
|
|
74
|
-
|
|
75
|
-
graph
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
59
|
+
```typescript
|
|
60
|
+
import { GraphBuilder } from "@graphty/graph-format";
|
|
61
|
+
import { indexed } from "@graphty/algorithms";
|
|
62
|
+
|
|
63
|
+
// Build and freeze a graph; nodes are added on first mention, indices in that order
|
|
64
|
+
const builder = new GraphBuilder({ directed: false });
|
|
65
|
+
builder.addEdge("A", "B", 1); // source, target, weight
|
|
66
|
+
builder.addEdge("B", "C", 2);
|
|
67
|
+
const graph = builder.freeze();
|
|
80
68
|
|
|
81
|
-
// Basic graph operations
|
|
82
69
|
console.log(graph.nodeCount); // 3
|
|
83
|
-
console.log(graph.
|
|
84
|
-
console.log(graph.hasEdge("A", "B")); // true
|
|
70
|
+
console.log(graph.edgeCount); // 2
|
|
85
71
|
|
|
86
|
-
// Run algorithms
|
|
87
|
-
const
|
|
88
|
-
|
|
72
|
+
// Run algorithms; ids map to indices and back only at the boundary
|
|
73
|
+
const start = graph.ids.requireIndex("A");
|
|
74
|
+
const traversal = indexed.breadthFirstSearch(graph, start);
|
|
75
|
+
console.log(Array.from(traversal.order.subarray(0, traversal.visitedCount), (i) => graph.ids.idOf(i))); // ["A", "B", "C"]
|
|
89
76
|
|
|
90
|
-
const shortestPaths = dijkstra(graph,
|
|
91
|
-
//
|
|
92
|
-
const pathToC = shortestPaths.get("C");
|
|
93
|
-
console.log(pathToC?.distance); // 3
|
|
77
|
+
const shortestPaths = indexed.dijkstra(graph, start);
|
|
78
|
+
console.log(shortestPaths.dist[graph.ids.requireIndex("C")]); // 3
|
|
94
79
|
```
|
|
95
80
|
|
|
81
|
+
The id-keyed API documented below (the `Graph` class and functions such as `breadthFirstSearch(graph, "A")`) is the
|
|
82
|
+
previous API. It stays available until the next major version; `toSnapshot(graph)` converts one of its graphs to a
|
|
83
|
+
snapshot.
|
|
84
|
+
|
|
96
85
|
## API Reference
|
|
97
86
|
|
|
98
87
|
### Graph Class
|
|
@@ -227,10 +216,7 @@ const result = breadthFirstSearch(graph, startNode, {
|
|
|
227
216
|
});
|
|
228
217
|
// Returns: TraversalResult { visited: Set<NodeId>, order: NodeId[], tree?: Map<NodeId, NodeId | null> }
|
|
229
218
|
|
|
230
|
-
//
|
|
231
|
-
// - Direction-Optimized BFS (switches between top-down/bottom-up)
|
|
232
|
-
// - CSR graph format for cache efficiency
|
|
233
|
-
// - Bit-packed data structures for memory efficiency
|
|
219
|
+
// For a direction-optimising BFS over a large graph, see indexed.directionOptimizedBfs.
|
|
234
220
|
|
|
235
221
|
// Find shortest path between two nodes (unweighted)
|
|
236
222
|
const path = shortestPathBFS(graph, source, target);
|
|
@@ -328,6 +314,31 @@ const result = hasNegativeCycle(graph);
|
|
|
328
314
|
// Returns: BellmanFordResult with hasNegativeCycle boolean
|
|
329
315
|
```
|
|
330
316
|
|
|
317
|
+
##### Index-based Bellman-Ford and point-to-point paths
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
import { accelerated, indexed, toSnapshot } from "@graphty/algorithms";
|
|
321
|
+
|
|
322
|
+
const s = toSnapshot(graph);
|
|
323
|
+
const a = s.ids.requireIndex("a");
|
|
324
|
+
const c = s.ids.requireIndex("c");
|
|
325
|
+
|
|
326
|
+
const bf = indexed.bellmanFord(s, a); // or: await accelerated(acc).bellmanFord(s, a)
|
|
327
|
+
// { dist, predArc, hasNegativeCycle, pathTo(i), pathEdges(i) } -- node and edge indices
|
|
328
|
+
|
|
329
|
+
const shortest = indexed.bidirectionalDijkstra(s, a, c);
|
|
330
|
+
const guided = indexed.astar(s, a, c, (i, goal) => estimate(i, goal)); // heuristic over node indices
|
|
331
|
+
// { distance, path, edges }; distance is Infinity and both arrays empty when c is unreachable
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
Bellman-Ford relaxes an undirected edge both ways, so one negative undirected edge is a negative
|
|
335
|
+
cycle. Every path records the edge it took, so of two parallel edges the path names the one used.
|
|
336
|
+
Each takes a per-arc `weights` override for weights other than the snapshot's own.
|
|
337
|
+
|
|
338
|
+
Where two paths cost the same, a port may take a different one from the legacy function (whose
|
|
339
|
+
choice follows its map and queue order, and changes with graph size in `dijkstraPath`), and a
|
|
340
|
+
distance summed from decimal weights may then differ from legacy's in the last bit.
|
|
341
|
+
|
|
331
342
|
#### Floyd-Warshall Algorithm
|
|
332
343
|
|
|
333
344
|
```typescript
|
|
@@ -346,6 +357,28 @@ const closure = transitiveClosure(graph);
|
|
|
346
357
|
// Returns: Map<NodeId, Set<NodeId>>
|
|
347
358
|
```
|
|
348
359
|
|
|
360
|
+
##### Index-based all-pairs shortest paths
|
|
361
|
+
|
|
362
|
+
```typescript
|
|
363
|
+
import { indexed, toSnapshot } from "@graphty/algorithms";
|
|
364
|
+
|
|
365
|
+
const s = toSnapshot(graph);
|
|
366
|
+
const { dist, n } = indexed.allPairsShortestPath(s);
|
|
367
|
+
const i = s.ids.requireIndex("a");
|
|
368
|
+
const j = s.ids.requireIndex("c");
|
|
369
|
+
console.log(dist[i * n + j]); // distance from a to c; +Infinity when unreachable
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
By default it runs one breadth-first search per source on unweighted graphs, Floyd-Warshall when a
|
|
373
|
+
weight is negative or the graph is dense (n^2 / 3 arcs or more), and one Dijkstra per source
|
|
374
|
+
otherwise; `method: "floyd-warshall"` or `"per-source"` forces a strategy, and `result.method` says
|
|
375
|
+
which ran. Pass `paths: true` to record predecessors, then `pathTo(i, j)` and `pathEdges(i, j)` return
|
|
376
|
+
node and edge indices. It refuses graphs above 5,792 nodes (256 MiB of matrix) unless you raise
|
|
377
|
+
`maxNodes`. A negative cycle gives `hasNegativeCycle: true` and a matrix of `NaN`. On a 512-node graph
|
|
378
|
+
with 5,120 edges it was 69x faster than the Map-of-Maps Floyd-Warshall that `floydWarshall` ran before it
|
|
379
|
+
delegated here, with Floyd-Warshall forced, 201x on weighted input by default, and 775x on unweighted
|
|
380
|
+
input.
|
|
381
|
+
|
|
349
382
|
### Centrality Algorithms
|
|
350
383
|
|
|
351
384
|
#### Degree Centrality
|
|
@@ -419,6 +452,26 @@ const centrality = nodeWeightedClosenessCentrality(graph, nodeId, {
|
|
|
419
452
|
// Returns: number
|
|
420
453
|
```
|
|
421
454
|
|
|
455
|
+
##### Index-based degree, closeness and betweenness
|
|
456
|
+
|
|
457
|
+
```typescript
|
|
458
|
+
import { indexed, toSnapshot } from "@graphty/algorithms";
|
|
459
|
+
|
|
460
|
+
const s = toSnapshot(graph);
|
|
461
|
+
const degree = indexed.degreeCentrality(s, { normalized: true }); // Float64Array, one score per node index
|
|
462
|
+
const closeness = indexed.closenessCentrality(s, { weighted: true }).scores;
|
|
463
|
+
const one = indexed.nodeClosenessCentrality(s, s.ids.requireIndex("a"));
|
|
464
|
+
const betweenness = indexed.betweennessCentrality(s, { k: 100 }).scores; // 100 sampled sources
|
|
465
|
+
const edges = indexed.edgeBetweennessCentrality(s).scores; // one score per edge index
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
These return the legacy functions' scores in typed arrays indexed by node (or edge) index. A multigraph
|
|
469
|
+
counts each pair's parallel edges once, and weighted closeness takes the lightest of them. Weighted
|
|
470
|
+
closeness reads the snapshot's f32 weights; pass the f64 weights as `weights` for the exact legacy sums.
|
|
471
|
+
Betweenness takes explicit `sources` or a deterministic draw of `k` of them, and a sampled result is
|
|
472
|
+
the unscaled sum over those sources. `edgeBetweennessCentrality` takes an `alive` edge mask that treats
|
|
473
|
+
the cleared edges as deleted.
|
|
474
|
+
|
|
422
475
|
#### PageRank
|
|
423
476
|
|
|
424
477
|
```typescript
|
|
@@ -448,6 +501,15 @@ const centralities = pageRankCentrality(graph, options);
|
|
|
448
501
|
// Returns: CentralityResult (Record<string, number>)
|
|
449
502
|
```
|
|
450
503
|
|
|
504
|
+
Over a `@graphty/graph-format` snapshot, `new indexed.DeltaPageRank(s)` and `new indexed.PriorityDeltaPageRank(s)` are the snapshot
|
|
505
|
+
counterparts of `DeltaPageRank` and `PriorityDeltaPageRank`, with the same state kept between
|
|
506
|
+
calls; `update()` takes node indices and skips any outside the graph. A snapshot stores edge
|
|
507
|
+
weights in single precision, and both engines divide by the weighted out-degree even when
|
|
508
|
+
`weighted` is false, so a graph whose weights are not exact in single precision gives scores that
|
|
509
|
+
differ from the legacy engines in about the seventh significant digit. For the legacy scores to
|
|
510
|
+
full double precision, pass the double-precision weights of every arc as `{ weights }` (arcCount
|
|
511
|
+
long, in arc order); a vector of any other length throws a `RangeError`.
|
|
512
|
+
|
|
451
513
|
#### Eigenvector Centrality
|
|
452
514
|
|
|
453
515
|
```typescript
|
|
@@ -645,6 +707,11 @@ const mst = primMST(graph, startNode?);
|
|
|
645
707
|
// Returns: { edges: Edge[], weight: number }
|
|
646
708
|
```
|
|
647
709
|
|
|
710
|
+
Over a snapshot, `indexed.primMST(s, { start, forest })` returns `{ edges, totalWeight, predArc }`:
|
|
711
|
+
logical edge indices in the order they joined the tree, and the arc that reached each node. With
|
|
712
|
+
`forest: true` it grows a tree in every component instead of throwing on a disconnected graph.
|
|
713
|
+
Where edge weights tie, it may pick a different tree of the same weight from legacy `primMST`.
|
|
714
|
+
|
|
648
715
|
### Community Detection Algorithms
|
|
649
716
|
|
|
650
717
|
#### Louvain Method
|
|
@@ -674,6 +741,10 @@ const communities = leiden(graph, {
|
|
|
674
741
|
// Returns: { communities: Map<NodeId, number>, modularity: number }
|
|
675
742
|
```
|
|
676
743
|
|
|
744
|
+
Over a `@graphty/graph-format` snapshot, `indexed.leiden(s, { resolution, randomSeed, maxIterations, threshold })`
|
|
745
|
+
returns `{ labels, count, groups(), modularity, iterations }` with every community connected. Its
|
|
746
|
+
`maxIterations` caps whole passes (each running every level it needs), not single levels.
|
|
747
|
+
|
|
677
748
|
#### Label Propagation
|
|
678
749
|
|
|
679
750
|
```typescript
|
|
@@ -692,6 +763,20 @@ const labels = labelPropagationAsync(graph, options);
|
|
|
692
763
|
const labels = labelPropagationSemiSupervised(graph, seedLabels, options);
|
|
693
764
|
```
|
|
694
765
|
|
|
766
|
+
Over a `@graphty/graph-format` snapshot, `indexed.labelPropagation(toSnapshot(graph), { maxIterations,
|
|
767
|
+
randomSeed, weighted })` runs fast label propagation (FLPA) on typed arrays and returns
|
|
768
|
+
`{ labels, count, groups(), iterations, converged }`. It stops once every label is dominant, so it
|
|
769
|
+
also converges on paths and trees. `labelPropagation` delegates to it, so for the same integer seed both
|
|
770
|
+
return the same partition.
|
|
771
|
+
|
|
772
|
+
`indexed.labelPropagationSemiSupervised(s, seeds, options)` runs the same kernel with some nodes held:
|
|
773
|
+
`seeds` is a `Uint32Array` with one entry per node, a fixed label or `INVALID_INDEX` for a free node.
|
|
774
|
+
Seeds with equal labels share a community and seeds with different labels never do; the result is
|
|
775
|
+
renumbered, so read a seed's community through `labels[seedNode]`.
|
|
776
|
+
`indexed.labelPropagationSynchronous(s, { maxIterations, weighted })` updates every node at once from
|
|
777
|
+
the previous pass, with no random stream, alternating up and down passes so neighbours cannot swap
|
|
778
|
+
labels for ever.
|
|
779
|
+
|
|
695
780
|
#### Girvan-Newman Algorithm
|
|
696
781
|
|
|
697
782
|
```typescript
|
|
@@ -704,6 +789,10 @@ const dendrogram = girvanNewman(graph, {
|
|
|
704
789
|
// Returns: { levels: Array<{ modularity: number, communities: NodeId[][] }> }
|
|
705
790
|
```
|
|
706
791
|
|
|
792
|
+
Over a snapshot, `indexed.girvanNewman(s, { maxCommunities, minCommunitySize, maxIterations })` returns
|
|
793
|
+
`{ levels, modularity }`: one `Uint32Array` partition per level, the uncut graph first, and the
|
|
794
|
+
modularity of each level.
|
|
795
|
+
|
|
707
796
|
### Pathfinding Algorithms
|
|
708
797
|
|
|
709
798
|
#### A\* Algorithm
|