@graphty/algorithms 1.2.0 → 1.4.2
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 +375 -276
- package/dist/algorithms.d.ts +42 -2
- package/dist/algorithms.js +11402 -2
- package/dist/algorithms.js.map +1 -1
- package/dist/src/algorithms/centrality/betweenness.d.ts +14 -0
- package/dist/src/algorithms/centrality/betweenness.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/betweenness.js +144 -169
- package/dist/src/algorithms/centrality/betweenness.js.map +1 -1
- package/dist/src/algorithms/centrality/closeness.d.ts +35 -1
- package/dist/src/algorithms/centrality/closeness.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/closeness.js +70 -149
- package/dist/src/algorithms/centrality/closeness.js.map +1 -1
- package/dist/src/algorithms/centrality/degree.d.ts +7 -0
- package/dist/src/algorithms/centrality/degree.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/degree.js +12 -9
- package/dist/src/algorithms/centrality/degree.js.map +1 -1
- package/dist/src/algorithms/centrality/delta-pagerank-simple.d.ts +57 -0
- package/dist/src/algorithms/centrality/delta-pagerank-simple.d.ts.map +1 -0
- package/dist/src/algorithms/centrality/delta-pagerank-simple.js +304 -0
- package/dist/src/algorithms/centrality/delta-pagerank-simple.js.map +1 -0
- package/dist/src/algorithms/centrality/delta-pagerank.d.ts +106 -0
- package/dist/src/algorithms/centrality/delta-pagerank.d.ts.map +1 -0
- package/dist/src/algorithms/centrality/delta-pagerank.js +320 -0
- package/dist/src/algorithms/centrality/delta-pagerank.js.map +1 -0
- package/dist/src/algorithms/centrality/eigenvector.d.ts +10 -3
- package/dist/src/algorithms/centrality/eigenvector.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/eigenvector.js +11 -4
- package/dist/src/algorithms/centrality/eigenvector.js.map +1 -1
- package/dist/src/algorithms/centrality/hits.d.ts +10 -3
- package/dist/src/algorithms/centrality/hits.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/hits.js +11 -4
- package/dist/src/algorithms/centrality/hits.js.map +1 -1
- package/dist/src/algorithms/centrality/index.d.ts +3 -1
- package/dist/src/algorithms/centrality/index.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/index.js +2 -1
- package/dist/src/algorithms/centrality/index.js.map +1 -1
- package/dist/src/algorithms/centrality/katz.d.ts +10 -3
- package/dist/src/algorithms/centrality/katz.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/katz.js +13 -8
- package/dist/src/algorithms/centrality/katz.js.map +1 -1
- package/dist/src/algorithms/centrality/pagerank.d.ts +31 -0
- package/dist/src/algorithms/centrality/pagerank.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/pagerank.js +61 -1
- package/dist/src/algorithms/centrality/pagerank.js.map +1 -1
- package/dist/src/algorithms/community/girvan-newman.d.ts +2 -3
- package/dist/src/algorithms/community/girvan-newman.d.ts.map +1 -1
- package/dist/src/algorithms/community/girvan-newman.js +67 -57
- package/dist/src/algorithms/community/girvan-newman.js.map +1 -1
- package/dist/src/algorithms/community/index.d.ts +2 -0
- package/dist/src/algorithms/community/index.d.ts.map +1 -1
- package/dist/src/algorithms/community/index.js.map +1 -1
- package/dist/src/algorithms/community/label-propagation.d.ts +11 -4
- package/dist/src/algorithms/community/label-propagation.d.ts.map +1 -1
- package/dist/src/algorithms/community/label-propagation.js +60 -38
- package/dist/src/algorithms/community/label-propagation.js.map +1 -1
- package/dist/src/algorithms/community/leiden.d.ts +3 -3
- package/dist/src/algorithms/community/leiden.d.ts.map +1 -1
- package/dist/src/algorithms/community/leiden.js +70 -44
- package/dist/src/algorithms/community/leiden.js.map +1 -1
- package/dist/src/algorithms/community/louvain-optimized.d.ts +149 -0
- package/dist/src/algorithms/community/louvain-optimized.d.ts.map +1 -0
- package/dist/src/algorithms/community/louvain-optimized.js +338 -0
- package/dist/src/algorithms/community/louvain-optimized.js.map +1 -0
- package/dist/src/algorithms/community/louvain.d.ts +2 -3
- package/dist/src/algorithms/community/louvain.d.ts.map +1 -1
- package/dist/src/algorithms/community/louvain.js +35 -81
- package/dist/src/algorithms/community/louvain.js.map +1 -1
- package/dist/src/algorithms/community/modularity-utils.d.ts +55 -0
- package/dist/src/algorithms/community/modularity-utils.d.ts.map +1 -0
- package/dist/src/algorithms/community/modularity-utils.js +108 -0
- package/dist/src/algorithms/community/modularity-utils.js.map +1 -0
- package/dist/src/algorithms/components/connected.d.ts +23 -0
- package/dist/src/algorithms/components/connected.d.ts.map +1 -1
- package/dist/src/algorithms/components/connected.js +29 -3
- package/dist/src/algorithms/components/connected.js.map +1 -1
- package/dist/src/algorithms/matching/bipartite.d.ts +10 -0
- package/dist/src/algorithms/matching/bipartite.d.ts.map +1 -1
- package/dist/src/algorithms/matching/bipartite.js +18 -40
- package/dist/src/algorithms/matching/bipartite.js.map +1 -1
- package/dist/src/algorithms/matching/index.d.ts.map +1 -1
- package/dist/src/algorithms/matching/index.js.map +1 -1
- package/dist/src/algorithms/matching/isomorphism.d.ts +8 -0
- package/dist/src/algorithms/matching/isomorphism.d.ts.map +1 -1
- package/dist/src/algorithms/matching/isomorphism.js +36 -2
- package/dist/src/algorithms/matching/isomorphism.js.map +1 -1
- package/dist/src/algorithms/mst/index.d.ts.map +1 -1
- package/dist/src/algorithms/mst/index.js.map +1 -1
- package/dist/src/algorithms/mst/kruskal.d.ts +14 -0
- package/dist/src/algorithms/mst/kruskal.d.ts.map +1 -1
- package/dist/src/algorithms/mst/kruskal.js +17 -3
- package/dist/src/algorithms/mst/kruskal.js.map +1 -1
- package/dist/src/algorithms/mst/prim.d.ts +9 -0
- package/dist/src/algorithms/mst/prim.d.ts.map +1 -1
- package/dist/src/algorithms/mst/prim.js +9 -0
- package/dist/src/algorithms/mst/prim.js.map +1 -1
- package/dist/src/algorithms/shortest-path/bellman-ford.d.ts +10 -0
- package/dist/src/algorithms/shortest-path/bellman-ford.d.ts.map +1 -1
- package/dist/src/algorithms/shortest-path/bellman-ford.js +11 -12
- package/dist/src/algorithms/shortest-path/bellman-ford.js.map +1 -1
- package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.d.ts +44 -0
- package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.d.ts.map +1 -0
- package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.js +195 -0
- package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.js.map +1 -0
- package/dist/src/algorithms/shortest-path/dijkstra.d.ts +20 -2
- package/dist/src/algorithms/shortest-path/dijkstra.d.ts.map +1 -1
- package/dist/src/algorithms/shortest-path/dijkstra.js +30 -14
- package/dist/src/algorithms/shortest-path/dijkstra.js.map +1 -1
- package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts +17 -0
- package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts.map +1 -1
- package/dist/src/algorithms/shortest-path/floyd-warshall.js +17 -0
- package/dist/src/algorithms/shortest-path/floyd-warshall.js.map +1 -1
- package/dist/src/algorithms/shortest-path/index.d.ts.map +1 -1
- package/dist/src/algorithms/shortest-path/index.js.map +1 -1
- package/dist/src/algorithms/traversal/bfs-unified.d.ts +42 -0
- package/dist/src/algorithms/traversal/bfs-unified.d.ts.map +1 -0
- package/dist/src/algorithms/traversal/bfs-unified.js +370 -0
- package/dist/src/algorithms/traversal/bfs-unified.js.map +1 -0
- package/dist/src/algorithms/traversal/bfs-variants.d.ts +77 -0
- package/dist/src/algorithms/traversal/bfs-variants.d.ts.map +1 -0
- package/dist/src/algorithms/traversal/bfs-variants.js +402 -0
- package/dist/src/algorithms/traversal/bfs-variants.js.map +1 -0
- package/dist/src/algorithms/traversal/bfs.d.ts +4 -18
- package/dist/src/algorithms/traversal/bfs.d.ts.map +1 -1
- package/dist/src/algorithms/traversal/bfs.js +5 -182
- package/dist/src/algorithms/traversal/bfs.js.map +1 -1
- package/dist/src/algorithms/traversal/dfs.d.ts +10 -0
- package/dist/src/algorithms/traversal/dfs.d.ts.map +1 -1
- package/dist/src/algorithms/traversal/dfs.js +48 -0
- package/dist/src/algorithms/traversal/dfs.js.map +1 -1
- package/dist/src/algorithms/traversal/index.d.ts.map +1 -1
- package/dist/src/algorithms/traversal/index.js.map +1 -1
- package/dist/src/benchmark-all-algorithms.d.ts +25 -0
- package/dist/src/benchmark-all-algorithms.d.ts.map +1 -0
- package/dist/src/benchmark-all-algorithms.js +491 -0
- package/dist/src/benchmark-all-algorithms.js.map +1 -0
- package/dist/src/clustering/hierarchical.d.ts +23 -15
- package/dist/src/clustering/hierarchical.d.ts.map +1 -1
- package/dist/src/clustering/hierarchical.js +226 -224
- package/dist/src/clustering/hierarchical.js.map +1 -1
- package/dist/src/clustering/index.d.ts +4 -2
- package/dist/src/clustering/index.d.ts.map +1 -1
- package/dist/src/clustering/index.js +2 -2
- package/dist/src/clustering/index.js.map +1 -1
- package/dist/src/clustering/k-core.d.ts +17 -19
- package/dist/src/clustering/k-core.d.ts.map +1 -1
- package/dist/src/clustering/k-core.js +68 -30
- package/dist/src/clustering/k-core.js.map +1 -1
- package/dist/src/clustering/mcl.d.ts +6 -0
- package/dist/src/clustering/mcl.d.ts.map +1 -1
- package/dist/src/clustering/mcl.js +34 -3
- package/dist/src/clustering/mcl.js.map +1 -1
- package/dist/src/clustering/spectral.d.ts +11 -0
- package/dist/src/clustering/spectral.d.ts.map +1 -1
- package/dist/src/clustering/spectral.js +99 -47
- package/dist/src/clustering/spectral.js.map +1 -1
- package/dist/src/core/graph.d.ts +45 -0
- package/dist/src/core/graph.d.ts.map +1 -1
- package/dist/src/core/graph.js +49 -5
- package/dist/src/core/graph.js.map +1 -1
- package/dist/src/data-structures/index.d.ts.map +1 -1
- package/dist/src/data-structures/index.js.map +1 -1
- package/dist/src/data-structures/priority-queue.d.ts +18 -1
- package/dist/src/data-structures/priority-queue.d.ts.map +1 -1
- package/dist/src/data-structures/priority-queue.js +26 -5
- package/dist/src/data-structures/priority-queue.js.map +1 -1
- package/dist/src/data-structures/union-find.d.ts +21 -0
- package/dist/src/data-structures/union-find.d.ts.map +1 -1
- package/dist/src/data-structures/union-find.js +21 -0
- package/dist/src/data-structures/union-find.js.map +1 -1
- package/dist/src/flow/ford-fulkerson.d.ts +20 -12
- package/dist/src/flow/ford-fulkerson.d.ts.map +1 -1
- package/dist/src/flow/ford-fulkerson.js +170 -217
- package/dist/src/flow/ford-fulkerson.js.map +1 -1
- package/dist/src/flow/min-cut.d.ts +6 -8
- package/dist/src/flow/min-cut.d.ts.map +1 -1
- package/dist/src/flow/min-cut.js +34 -12
- package/dist/src/flow/min-cut.js.map +1 -1
- package/dist/src/index.d.ts +3 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +6 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/link-prediction/adamic-adar.d.ts +26 -0
- package/dist/src/link-prediction/adamic-adar.d.ts.map +1 -1
- package/dist/src/link-prediction/adamic-adar.js +47 -30
- package/dist/src/link-prediction/adamic-adar.js.map +1 -1
- package/dist/src/link-prediction/common-neighbors.d.ts +21 -0
- package/dist/src/link-prediction/common-neighbors.d.ts.map +1 -1
- package/dist/src/link-prediction/common-neighbors.js +31 -14
- package/dist/src/link-prediction/common-neighbors.js.map +1 -1
- package/dist/src/link-prediction/index.d.ts.map +1 -1
- package/dist/src/optimized/bit-packed.d.ts +193 -0
- package/dist/src/optimized/bit-packed.d.ts.map +1 -0
- package/dist/src/optimized/bit-packed.js +342 -0
- package/dist/src/optimized/bit-packed.js.map +1 -0
- package/dist/src/optimized/csr-graph.d.ts +149 -0
- package/dist/src/optimized/csr-graph.d.ts.map +1 -0
- package/dist/src/optimized/csr-graph.js +404 -0
- package/dist/src/optimized/csr-graph.js.map +1 -0
- package/dist/src/optimized/direction-optimized-bfs.d.ts +95 -0
- package/dist/src/optimized/direction-optimized-bfs.d.ts.map +1 -0
- package/dist/src/optimized/direction-optimized-bfs.js +242 -0
- package/dist/src/optimized/direction-optimized-bfs.js.map +1 -0
- package/dist/src/optimized/graph-adapter.d.ts +111 -0
- package/dist/src/optimized/graph-adapter.d.ts.map +1 -0
- package/dist/src/optimized/graph-adapter.js +194 -0
- package/dist/src/optimized/graph-adapter.js.map +1 -0
- package/dist/src/optimized/index.d.ts +14 -0
- package/dist/src/optimized/index.d.ts.map +1 -0
- package/dist/src/optimized/index.js +30 -0
- package/dist/src/optimized/index.js.map +1 -0
- package/dist/src/pathfinding/astar.d.ts +25 -9
- package/dist/src/pathfinding/astar.d.ts.map +1 -1
- package/dist/src/pathfinding/astar.js +25 -10
- package/dist/src/pathfinding/astar.js.map +1 -1
- package/dist/src/pathfinding/utils.d.ts +15 -6
- package/dist/src/pathfinding/utils.d.ts.map +1 -1
- package/dist/src/pathfinding/utils.js +19 -7
- package/dist/src/pathfinding/utils.js.map +1 -1
- package/dist/src/research/grsbm.d.ts +0 -1
- package/dist/src/research/grsbm.d.ts.map +1 -1
- package/dist/src/research/grsbm.js +28 -23
- package/dist/src/research/grsbm.js.map +1 -1
- package/dist/src/research/index.d.ts.map +1 -1
- package/dist/src/research/index.js.map +1 -1
- package/dist/src/research/sync.d.ts +0 -1
- package/dist/src/research/sync.d.ts.map +1 -1
- package/dist/src/research/sync.js +31 -36
- package/dist/src/research/sync.js.map +1 -1
- package/dist/src/research/terahac.d.ts +2 -1
- package/dist/src/research/terahac.d.ts.map +1 -1
- package/dist/src/research/terahac.js +39 -7
- package/dist/src/research/terahac.js.map +1 -1
- package/dist/src/types/index.d.ts +8 -0
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/utils/algorithm-utilities.d.ts +2 -0
- package/dist/src/utils/algorithm-utilities.d.ts.map +1 -0
- package/dist/src/utils/algorithm-utilities.js +2 -0
- package/dist/src/utils/algorithm-utilities.js.map +1 -0
- package/dist/src/utils/graph-converters.d.ts +110 -0
- package/dist/src/utils/graph-converters.d.ts.map +1 -0
- package/dist/src/utils/graph-converters.js +227 -0
- package/dist/src/utils/graph-converters.js.map +1 -0
- package/dist/src/utils/graph-utilities.d.ts +62 -0
- package/dist/src/utils/graph-utilities.d.ts.map +1 -0
- package/dist/src/utils/graph-utilities.js +148 -0
- package/dist/src/utils/graph-utilities.js.map +1 -0
- package/dist/src/utils/index.d.ts +5 -0
- package/dist/src/utils/index.d.ts.map +1 -0
- package/dist/src/utils/index.js +5 -0
- package/dist/src/utils/index.js.map +1 -0
- package/dist/src/utils/math-utilities.d.ts +63 -0
- package/dist/src/utils/math-utilities.d.ts.map +1 -0
- package/dist/src/utils/math-utilities.js +132 -0
- package/dist/src/utils/math-utilities.js.map +1 -0
- package/dist/src/utils/matrix-utilities.d.ts +2 -0
- package/dist/src/utils/matrix-utilities.d.ts.map +1 -0
- package/dist/src/utils/matrix-utilities.js +2 -0
- package/dist/src/utils/matrix-utilities.js.map +1 -0
- package/dist/src/utils/optimization-helpers.d.ts +42 -0
- package/dist/src/utils/optimization-helpers.d.ts.map +1 -0
- package/dist/src/utils/optimization-helpers.js +59 -0
- package/dist/src/utils/optimization-helpers.js.map +1 -0
- package/dist/src/utils/priorityQueue.d.ts +24 -0
- package/dist/src/utils/priorityQueue.d.ts.map +1 -1
- package/dist/src/utils/priorityQueue.js +34 -4
- package/dist/src/utils/priorityQueue.js.map +1 -1
- package/package.json +58 -39
- package/src/algorithms/centrality/betweenness.ts +185 -200
- package/src/algorithms/centrality/closeness.ts +93 -194
- package/src/algorithms/centrality/degree.ts +18 -22
- package/src/algorithms/centrality/delta-pagerank-simple.ts +374 -0
- package/src/algorithms/centrality/delta-pagerank.ts +458 -0
- package/src/algorithms/centrality/eigenvector.ts +14 -15
- package/src/algorithms/centrality/hits.ts +17 -17
- package/src/algorithms/centrality/index.ts +20 -13
- package/src/algorithms/centrality/katz.ts +17 -25
- package/src/algorithms/centrality/pagerank.ts +91 -16
- package/src/algorithms/community/girvan-newman.ts +90 -86
- package/src/algorithms/community/index.ts +6 -5
- package/src/algorithms/community/label-propagation.ts +69 -48
- package/src/algorithms/community/leiden.ts +88 -65
- package/src/algorithms/community/louvain-optimized.ts +474 -0
- package/src/algorithms/community/louvain.ts +52 -122
- package/src/algorithms/community/modularity-utils.ts +134 -0
- package/src/algorithms/components/connected.ts +40 -17
- package/src/algorithms/matching/bipartite.ts +24 -53
- package/src/algorithms/matching/index.ts +4 -4
- package/src/algorithms/matching/isomorphism.ts +53 -23
- package/src/algorithms/mst/index.ts +3 -4
- package/src/algorithms/mst/kruskal.ts +21 -6
- package/src/algorithms/mst/prim.ts +13 -4
- package/src/algorithms/shortest-path/bellman-ford.ts +16 -28
- package/src/algorithms/shortest-path/bidirectional-dijkstra.ts +248 -0
- package/src/algorithms/shortest-path/dijkstra.ts +38 -30
- package/src/algorithms/shortest-path/floyd-warshall.ts +21 -4
- package/src/algorithms/shortest-path/index.ts +5 -5
- package/src/algorithms/traversal/bfs-unified.ts +437 -0
- package/src/algorithms/traversal/bfs-variants.ts +520 -0
- package/src/algorithms/traversal/bfs.ts +5 -229
- package/src/algorithms/traversal/dfs.ts +61 -42
- package/src/algorithms/traversal/index.ts +3 -3
- package/src/benchmark-all-algorithms.ts +580 -0
- package/src/clustering/hierarchical.ts +268 -272
- package/src/clustering/index.ts +8 -6
- package/src/clustering/k-core.ts +93 -61
- package/src/clustering/mcl.ts +53 -23
- package/src/clustering/spectral.ts +130 -72
- package/src/core/graph.ts +58 -18
- package/src/data-structures/index.ts +2 -2
- package/src/data-structures/priority-queue.ts +36 -11
- package/src/data-structures/union-find.ts +22 -1
- package/src/flow/ford-fulkerson.ts +221 -262
- package/src/flow/min-cut.ts +59 -51
- package/src/index.ts +9 -2
- package/src/link-prediction/adamic-adar.ts +75 -74
- package/src/link-prediction/common-neighbors.ts +49 -49
- package/src/link-prediction/index.ts +1 -1
- package/src/optimized/bit-packed.ts +390 -0
- package/src/optimized/csr-graph.ts +518 -0
- package/src/optimized/direction-optimized-bfs.ts +310 -0
- package/src/optimized/graph-adapter.ts +248 -0
- package/src/optimized/index.ts +34 -0
- package/src/pathfinding/astar.ts +40 -25
- package/src/pathfinding/utils.ts +20 -13
- package/src/research/grsbm.ts +36 -39
- package/src/research/index.ts +4 -4
- package/src/research/sync.ts +41 -54
- package/src/research/terahac.ts +63 -21
- package/src/types/index.ts +8 -0
- package/src/utils/algorithm-utilities.ts +2 -0
- package/src/utils/graph-converters.ts +269 -0
- package/src/utils/graph-utilities.ts +173 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/math-utilities.ts +149 -0
- package/src/utils/matrix-utilities.ts +2 -0
- package/src/utils/optimization-helpers.ts +87 -0
- package/src/utils/priorityQueue.ts +40 -6
package/README.md
CHANGED
|
@@ -4,18 +4,58 @@
|
|
|
4
4
|
[](https://coveralls.io/github/graphty-org/algorithms)
|
|
5
5
|
[](https://www.npmjs.com/package/@graphty/algorithms)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://graphty-org.github.io/algorithms/)
|
|
7
8
|
|
|
8
|
-
A comprehensive TypeScript graph algorithms library with
|
|
9
|
+
A comprehensive TypeScript graph algorithms library with 98 algorithms optimized for browser environments and visualization applications.
|
|
9
10
|
|
|
10
11
|
## Features
|
|
11
12
|
|
|
12
13
|
- **TypeScript-first**: Full type safety with comprehensive type definitions
|
|
13
14
|
- **Browser-optimized**: Designed to run efficiently in web browsers
|
|
14
15
|
- **Modular**: Import only the algorithms you need
|
|
15
|
-
- **Comprehensive**:
|
|
16
|
+
- **Comprehensive**: 98 graph algorithms including traversal, shortest paths, centrality, clustering, flow, matching, link prediction, and more
|
|
17
|
+
- **Interactive Examples**: [Live demos](https://graphty-org.github.io/algorithms/) with visualizations for all algorithms
|
|
18
|
+
- **Performance Analysis**: [Detailed benchmarks](https://graphty-org.github.io/algorithms/benchmarks/) comparing algorithm performance
|
|
16
19
|
- **Well-tested**: Extensive test suite with high coverage
|
|
17
20
|
- **Standards-compliant**: Follows conventional commits and semantic versioning
|
|
18
21
|
|
|
22
|
+
## Performance Optimizations
|
|
23
|
+
|
|
24
|
+
The library automatically optimizes performance for large graphs (≥10,000 nodes) using:
|
|
25
|
+
|
|
26
|
+
- **Direction-Optimized BFS**: Dynamically switches between top-down and bottom-up search strategies, providing up to 42x speedup on large graphs
|
|
27
|
+
- **CSR Graph Format**: Compressed Sparse Row format for cache-efficient memory access
|
|
28
|
+
- **Bit-Packed Data Structures**: 8x memory reduction using bit arrays for boolean data
|
|
29
|
+
|
|
30
|
+
These optimizations are applied automatically - no configuration needed! Just use the standard API:
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
// Automatically uses optimized implementation for large graphs
|
|
34
|
+
const result = breadthFirstSearch(largeGraph, startNode);
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
All BFS-based algorithms benefit from these optimizations:
|
|
38
|
+
|
|
39
|
+
- `breadthFirstSearch`, `shortestPathBFS`, `singleSourceShortestPathBFS`
|
|
40
|
+
- `betweennessCentrality`, `closenessCentrality`
|
|
41
|
+
- Connected component algorithms
|
|
42
|
+
|
|
43
|
+
### Performance Benchmarks
|
|
44
|
+
|
|
45
|
+
| Graph Size | Standard BFS | Optimized BFS | Speedup |
|
|
46
|
+
| ---------- | ------------ | ------------- | ------- |
|
|
47
|
+
| 10K nodes | 4.40ms | 6.34ms | 0.69x |
|
|
48
|
+
| 50K nodes | 158.64ms | 44.27ms | 3.58x |
|
|
49
|
+
| 100K nodes | 5,370ms | 126ms | 42.58x |
|
|
50
|
+
|
|
51
|
+
_Note: Optimizations activate automatically for graphs ≥10K nodes to avoid conversion overhead on smaller graphs._
|
|
52
|
+
|
|
53
|
+
### Learn More
|
|
54
|
+
|
|
55
|
+
- 📖 [Performance Guide](docs/PERFORMANCE_GUIDE.md) - Detailed optimization explanations
|
|
56
|
+
- 🔄 [Migration Guide](docs/MIGRATION_GUIDE.md) - Upgrading from older versions
|
|
57
|
+
- 💾 [Memory vs Speed Tradeoffs](docs/PERFORMANCE_GUIDE.md#memory-vs-speed-tradeoffs) - Making the right choices
|
|
58
|
+
|
|
19
59
|
## Installation
|
|
20
60
|
|
|
21
61
|
```bash
|
|
@@ -25,30 +65,30 @@ npm install @graphty/algorithms
|
|
|
25
65
|
## Quick Start
|
|
26
66
|
|
|
27
67
|
```typescript
|
|
28
|
-
import { Graph, breadthFirstSearch, dijkstra } from
|
|
68
|
+
import { Graph, breadthFirstSearch, dijkstra } from "@graphty/algorithms";
|
|
29
69
|
|
|
30
70
|
// Create a new graph
|
|
31
71
|
const graph = new Graph();
|
|
32
72
|
|
|
33
73
|
// Add nodes and edges
|
|
34
|
-
graph.addNode(
|
|
35
|
-
graph.addNode(
|
|
36
|
-
graph.addNode(
|
|
37
|
-
graph.addEdge(
|
|
38
|
-
graph.addEdge(
|
|
74
|
+
graph.addNode("A");
|
|
75
|
+
graph.addNode("B");
|
|
76
|
+
graph.addNode("C");
|
|
77
|
+
graph.addEdge("A", "B", 1); // source, target, weight
|
|
78
|
+
graph.addEdge("B", "C", 2);
|
|
39
79
|
|
|
40
80
|
// Basic graph operations
|
|
41
81
|
console.log(graph.nodeCount); // 3
|
|
42
82
|
console.log(graph.totalEdgeCount); // 2
|
|
43
|
-
console.log(graph.hasEdge(
|
|
83
|
+
console.log(graph.hasEdge("A", "B")); // true
|
|
44
84
|
|
|
45
85
|
// Run algorithms
|
|
46
|
-
const traversal = breadthFirstSearch(graph,
|
|
86
|
+
const traversal = breadthFirstSearch(graph, "A");
|
|
47
87
|
console.log(traversal.order); // ['A', 'B', 'C']
|
|
48
88
|
|
|
49
|
-
const shortestPaths = dijkstra(graph,
|
|
89
|
+
const shortestPaths = dijkstra(graph, "A");
|
|
50
90
|
// Get distance to C
|
|
51
|
-
const pathToC = shortestPaths.get(
|
|
91
|
+
const pathToC = shortestPaths.get("C");
|
|
52
92
|
console.log(pathToC?.distance); // 3
|
|
53
93
|
```
|
|
54
94
|
|
|
@@ -60,7 +100,7 @@ The core data structure for representing graphs.
|
|
|
60
100
|
|
|
61
101
|
```typescript
|
|
62
102
|
class Graph {
|
|
63
|
-
|
|
103
|
+
constructor(config?: Partial<GraphConfig>);
|
|
64
104
|
}
|
|
65
105
|
```
|
|
66
106
|
|
|
@@ -68,9 +108,9 @@ class Graph {
|
|
|
68
108
|
|
|
69
109
|
```typescript
|
|
70
110
|
interface GraphConfig {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
111
|
+
directed: boolean; // Default: false
|
|
112
|
+
allowSelfLoops: boolean; // Default: false
|
|
113
|
+
allowParallelEdges: boolean; // Default: false
|
|
74
114
|
}
|
|
75
115
|
```
|
|
76
116
|
|
|
@@ -98,9 +138,9 @@ graph.nodes(): IterableIterator<Node>
|
|
|
98
138
|
```typescript
|
|
99
139
|
// Add an edge with optional weight and data
|
|
100
140
|
graph.addEdge(
|
|
101
|
-
source: NodeId,
|
|
102
|
-
target: NodeId,
|
|
103
|
-
weight?: number,
|
|
141
|
+
source: NodeId,
|
|
142
|
+
target: NodeId,
|
|
143
|
+
weight?: number,
|
|
104
144
|
data?: Record<string, unknown>
|
|
105
145
|
): void
|
|
106
146
|
|
|
@@ -167,6 +207,9 @@ graph.clone(): Graph
|
|
|
167
207
|
|
|
168
208
|
// Clear all nodes and edges
|
|
169
209
|
graph.clear(): void
|
|
210
|
+
|
|
211
|
+
// Get a copy of the graph configuration
|
|
212
|
+
graph.getConfig(): GraphConfig
|
|
170
213
|
```
|
|
171
214
|
|
|
172
215
|
### Traversal Algorithms
|
|
@@ -178,18 +221,24 @@ import { breadthFirstSearch, shortestPathBFS, singleSourceShortestPathBFS, isBip
|
|
|
178
221
|
|
|
179
222
|
// Basic BFS traversal
|
|
180
223
|
const result = breadthFirstSearch(graph, startNode, {
|
|
181
|
-
|
|
182
|
-
visitCallback?: (node: NodeId,
|
|
224
|
+
targetNode?: NodeId, // Optional: stop when target is reached
|
|
225
|
+
visitCallback?: (node: NodeId, level: number) => void
|
|
183
226
|
});
|
|
184
|
-
// Returns: TraversalResult { visited: Set<NodeId>, order: NodeId[], tree?: Map<NodeId, NodeId> }
|
|
227
|
+
// Returns: TraversalResult { visited: Set<NodeId>, order: NodeId[], tree?: Map<NodeId, NodeId | null> }
|
|
228
|
+
|
|
229
|
+
// Note: For graphs with ≥10K nodes, BFS automatically uses:
|
|
230
|
+
// - Direction-Optimized BFS (switches between top-down/bottom-up)
|
|
231
|
+
// - CSR graph format for cache efficiency
|
|
232
|
+
// - Bit-packed data structures for memory efficiency
|
|
185
233
|
|
|
186
234
|
// Find shortest path between two nodes (unweighted)
|
|
187
235
|
const path = shortestPathBFS(graph, source, target);
|
|
188
|
-
// Returns:
|
|
236
|
+
// Returns: ShortestPathResult | null
|
|
237
|
+
// ShortestPathResult = { distance: number, path: NodeId[], predecessor: Map<NodeId, NodeId | null> }
|
|
189
238
|
|
|
190
239
|
// Find all shortest paths from a source
|
|
191
240
|
const paths = singleSourceShortestPathBFS(graph, source);
|
|
192
|
-
// Returns: Map<NodeId,
|
|
241
|
+
// Returns: Map<NodeId, ShortestPathResult>
|
|
193
242
|
|
|
194
243
|
// Check if graph is bipartite
|
|
195
244
|
const bipartite = isBipartite(graph);
|
|
@@ -203,8 +252,10 @@ import { depthFirstSearch, topologicalSort, hasCycleDFS, findStronglyConnectedCo
|
|
|
203
252
|
|
|
204
253
|
// Basic DFS traversal
|
|
205
254
|
const result = depthFirstSearch(graph, startNode, {
|
|
206
|
-
|
|
207
|
-
|
|
255
|
+
targetNode?: NodeId, // Optional: stop when target is reached
|
|
256
|
+
visitCallback?: (node: NodeId, level: number) => void,
|
|
257
|
+
recursive?: boolean, // Use recursive implementation (default: false)
|
|
258
|
+
preOrder?: boolean // Visit nodes in pre-order (default: true)
|
|
208
259
|
});
|
|
209
260
|
// Returns: TraversalResult
|
|
210
261
|
|
|
@@ -226,37 +277,42 @@ const sccs = findStronglyConnectedComponents(graph);
|
|
|
226
277
|
#### Dijkstra's Algorithm
|
|
227
278
|
|
|
228
279
|
```typescript
|
|
229
|
-
import {
|
|
280
|
+
import {
|
|
281
|
+
dijkstra,
|
|
282
|
+
dijkstraPath,
|
|
283
|
+
singleSourceShortestPath,
|
|
284
|
+
allPairsShortestPath
|
|
285
|
+
} from '@graphty/algorithms'
|
|
230
286
|
|
|
231
287
|
// Single-source shortest paths
|
|
232
288
|
const result = dijkstra(graph, source, {
|
|
233
|
-
target?: NodeId
|
|
234
|
-
})
|
|
289
|
+
target?: NodeId // Optional: stop when target is reached
|
|
290
|
+
})
|
|
235
291
|
// Returns: Map<NodeId, ShortestPathResult>
|
|
236
292
|
// ShortestPathResult = { distance: number, path: NodeId[], predecessor: Map<NodeId, NodeId | null> }
|
|
237
293
|
|
|
238
294
|
// Get specific path
|
|
239
|
-
const path = dijkstraPath(graph, source, target)
|
|
295
|
+
const path = dijkstraPath(graph, source, target)
|
|
240
296
|
// Returns: ShortestPathResult | null
|
|
241
297
|
|
|
242
298
|
// All shortest paths from source
|
|
243
|
-
const paths = singleSourceShortestPath(graph, source)
|
|
299
|
+
const paths = singleSourceShortestPath(graph, source)
|
|
244
300
|
// Returns: Map<NodeId, ShortestPathResult>
|
|
245
301
|
|
|
246
302
|
// All pairs shortest paths
|
|
247
|
-
const allPairs = allPairsShortestPath(graph)
|
|
303
|
+
const allPairs = allPairsShortestPath(graph)
|
|
248
304
|
// Returns: Map<NodeId, Map<NodeId, ShortestPathResult>>
|
|
249
305
|
```
|
|
250
306
|
|
|
251
307
|
#### Bellman-Ford Algorithm
|
|
252
308
|
|
|
253
309
|
```typescript
|
|
254
|
-
import { bellmanFord, bellmanFordPath, hasNegativeCycle } from
|
|
310
|
+
import { bellmanFord, bellmanFordPath, hasNegativeCycle } from "@graphty/algorithms";
|
|
255
311
|
|
|
256
312
|
// Single-source shortest paths (handles negative weights)
|
|
257
313
|
const result = bellmanFord(graph, source);
|
|
258
|
-
// Returns: BellmanFordResult {
|
|
259
|
-
// distances: Map<NodeId, number>,
|
|
314
|
+
// Returns: BellmanFordResult {
|
|
315
|
+
// distances: Map<NodeId, number>,
|
|
260
316
|
// predecessors: Map<NodeId, NodeId | null>,
|
|
261
317
|
// hasNegativeCycle: boolean,
|
|
262
318
|
// negativeCycleNodes?: Set<NodeId>
|
|
@@ -274,7 +330,7 @@ const result = hasNegativeCycle(graph);
|
|
|
274
330
|
#### Floyd-Warshall Algorithm
|
|
275
331
|
|
|
276
332
|
```typescript
|
|
277
|
-
import { floydWarshall, floydWarshallPath, transitiveClosure } from
|
|
333
|
+
import { floydWarshall, floydWarshallPath, transitiveClosure } from "@graphty/algorithms";
|
|
278
334
|
|
|
279
335
|
// All pairs shortest paths
|
|
280
336
|
const result = floydWarshall(graph);
|
|
@@ -294,30 +350,30 @@ const closure = transitiveClosure(graph);
|
|
|
294
350
|
#### Degree Centrality
|
|
295
351
|
|
|
296
352
|
```typescript
|
|
297
|
-
import { degreeCentrality, nodeDegreeCentrality } from
|
|
353
|
+
import { degreeCentrality, nodeDegreeCentrality } from "@graphty/algorithms";
|
|
298
354
|
|
|
299
355
|
// Calculate for all nodes
|
|
300
356
|
const centralities = degreeCentrality(graph, {
|
|
301
|
-
|
|
302
|
-
|
|
357
|
+
normalized: boolean, // Default: false
|
|
358
|
+
weight: string, // Optional: edge property for weighted degree
|
|
303
359
|
});
|
|
304
360
|
// Returns: CentralityResult (Record<string, number>)
|
|
305
361
|
|
|
306
362
|
// Calculate for single node
|
|
307
|
-
const centrality = nodeDegreeCentrality(graph, nodeId, { normalized
|
|
363
|
+
const centrality = nodeDegreeCentrality(graph, nodeId, { normalized: boolean });
|
|
308
364
|
// Returns: number
|
|
309
365
|
```
|
|
310
366
|
|
|
311
367
|
#### Betweenness Centrality
|
|
312
368
|
|
|
313
369
|
```typescript
|
|
314
|
-
import { betweennessCentrality, nodeBetweennessCentrality, edgeBetweennessCentrality } from
|
|
370
|
+
import { betweennessCentrality, nodeBetweennessCentrality, edgeBetweennessCentrality } from "@graphty/algorithms";
|
|
315
371
|
|
|
316
372
|
// Node betweenness for all nodes
|
|
317
373
|
const centralities = betweennessCentrality(graph, {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
374
|
+
normalized: boolean, // Default: false
|
|
375
|
+
weight: string, // Optional: use weighted shortest paths
|
|
376
|
+
endpoints: boolean, // Default: false, include endpoints in paths
|
|
321
377
|
});
|
|
322
378
|
// Returns: CentralityResult (Record<string, number>)
|
|
323
379
|
|
|
@@ -333,38 +389,47 @@ const edgeCentralities = edgeBetweennessCentrality(graph, options);
|
|
|
333
389
|
#### Closeness Centrality
|
|
334
390
|
|
|
335
391
|
```typescript
|
|
336
|
-
import { closenessCentrality, nodeClosenessCentrality, weightedClosenessCentrality } from
|
|
392
|
+
import { closenessCentrality, nodeClosenessCentrality, weightedClosenessCentrality } from "@graphty/algorithms";
|
|
337
393
|
|
|
338
394
|
// Closeness for all nodes
|
|
339
395
|
const centralities = closenessCentrality(graph, {
|
|
340
|
-
|
|
396
|
+
normalized: boolean, // Default: false
|
|
341
397
|
});
|
|
342
398
|
// Returns: CentralityResult (Record<string, number>)
|
|
343
399
|
|
|
344
400
|
// Single node closeness
|
|
345
|
-
const centrality = nodeClosenessCentrality(graph, nodeId, {
|
|
401
|
+
const centrality = nodeClosenessCentrality(graph, nodeId, {
|
|
402
|
+
normalized: boolean,
|
|
403
|
+
});
|
|
346
404
|
// Returns: number
|
|
347
405
|
|
|
348
406
|
// Weighted closeness
|
|
349
407
|
const centralities = weightedClosenessCentrality(graph, {
|
|
350
|
-
|
|
351
|
-
|
|
408
|
+
normalized: boolean,
|
|
409
|
+
weight: string, // Edge property for weights
|
|
352
410
|
});
|
|
353
411
|
// Returns: CentralityResult (Record<string, number>)
|
|
412
|
+
|
|
413
|
+
// Single node weighted closeness
|
|
414
|
+
const centrality = nodeWeightedClosenessCentrality(graph, nodeId, {
|
|
415
|
+
normalized: boolean,
|
|
416
|
+
weight: string, // Edge property for weights
|
|
417
|
+
});
|
|
418
|
+
// Returns: number
|
|
354
419
|
```
|
|
355
420
|
|
|
356
421
|
#### PageRank
|
|
357
422
|
|
|
358
423
|
```typescript
|
|
359
|
-
import { pageRank, personalizedPageRank, topPageRankNodes } from
|
|
424
|
+
import { pageRank, personalizedPageRank, topPageRankNodes } from "@graphty/algorithms";
|
|
360
425
|
|
|
361
426
|
// Standard PageRank
|
|
362
427
|
const result = pageRank(graph, {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
428
|
+
dampingFactor: number, // Default: 0.85
|
|
429
|
+
maxIterations: number, // Default: 100
|
|
430
|
+
tolerance: number, // Default: 1e-6
|
|
431
|
+
initialRanks: Record<string, number>,
|
|
432
|
+
personalization: Record<string, number>,
|
|
368
433
|
});
|
|
369
434
|
// Returns: { ranks: Record<string, number>, iterations: number, converged: boolean }
|
|
370
435
|
|
|
@@ -376,17 +441,21 @@ const ranks = personalizedPageRank(graph, personalization, options);
|
|
|
376
441
|
// Get top N nodes by PageRank
|
|
377
442
|
const topNodes = topPageRankNodes(graph, n, options);
|
|
378
443
|
// Returns: Array<{ node: NodeId, rank: number }>
|
|
444
|
+
|
|
445
|
+
// Alternative PageRank that returns CentralityResult format
|
|
446
|
+
const centralities = pageRankCentrality(graph, options);
|
|
447
|
+
// Returns: CentralityResult (Record<string, number>)
|
|
379
448
|
```
|
|
380
449
|
|
|
381
450
|
#### Eigenvector Centrality
|
|
382
451
|
|
|
383
452
|
```typescript
|
|
384
|
-
import { eigenvectorCentrality, nodeEigenvectorCentrality } from
|
|
453
|
+
import { eigenvectorCentrality, nodeEigenvectorCentrality } from "@graphty/algorithms";
|
|
385
454
|
|
|
386
455
|
// Calculate eigenvector centrality for all nodes
|
|
387
456
|
const centralities = eigenvectorCentrality(graph, {
|
|
388
|
-
|
|
389
|
-
|
|
457
|
+
maxIterations: number, // Default: 100
|
|
458
|
+
tolerance: number, // Default: 1e-6
|
|
390
459
|
});
|
|
391
460
|
// Returns: CentralityResult (Record<string, number>)
|
|
392
461
|
|
|
@@ -398,15 +467,15 @@ const centrality = nodeEigenvectorCentrality(graph, nodeId, options);
|
|
|
398
467
|
#### Katz Centrality
|
|
399
468
|
|
|
400
469
|
```typescript
|
|
401
|
-
import { katzCentrality, nodeKatzCentrality } from
|
|
470
|
+
import { katzCentrality, nodeKatzCentrality } from "@graphty/algorithms";
|
|
402
471
|
|
|
403
472
|
// Calculate Katz centrality for all nodes
|
|
404
473
|
const centralities = katzCentrality(graph, {
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
474
|
+
alpha: number, // Attenuation factor (default: 0.1)
|
|
475
|
+
beta: number, // Weight for direct connections (default: 1.0)
|
|
476
|
+
maxIterations: number, // Default: 100
|
|
477
|
+
tolerance: number, // Default: 1e-6
|
|
478
|
+
normalized: boolean, // Default: true
|
|
410
479
|
});
|
|
411
480
|
// Returns: CentralityResult (Record<string, number>)
|
|
412
481
|
|
|
@@ -418,12 +487,12 @@ const centrality = nodeKatzCentrality(graph, nodeId, options);
|
|
|
418
487
|
#### HITS Algorithm
|
|
419
488
|
|
|
420
489
|
```typescript
|
|
421
|
-
import { hits, nodeHITS } from
|
|
490
|
+
import { hits, nodeHITS } from "@graphty/algorithms";
|
|
422
491
|
|
|
423
492
|
// Calculate hub and authority scores
|
|
424
493
|
const result = hits(graph, {
|
|
425
|
-
|
|
426
|
-
|
|
494
|
+
maxIterations: number, // Default: 100
|
|
495
|
+
tolerance: number, // Default: 1e-6
|
|
427
496
|
});
|
|
428
497
|
// Returns: HITSResult { hubs: CentralityResult, authorities: CentralityResult }
|
|
429
498
|
|
|
@@ -437,13 +506,13 @@ const scores = nodeHITS(graph, nodeId, options);
|
|
|
437
506
|
#### Basic Component Operations
|
|
438
507
|
|
|
439
508
|
```typescript
|
|
440
|
-
import {
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
} from
|
|
509
|
+
import {
|
|
510
|
+
connectedComponents,
|
|
511
|
+
isConnected,
|
|
512
|
+
numberOfConnectedComponents,
|
|
513
|
+
largestConnectedComponent,
|
|
514
|
+
getConnectedComponent,
|
|
515
|
+
} from "@graphty/algorithms";
|
|
447
516
|
|
|
448
517
|
// Find all components
|
|
449
518
|
const components = connectedComponents(graph);
|
|
@@ -469,12 +538,12 @@ const component = getConnectedComponent(graph, nodeId);
|
|
|
469
538
|
#### Strongly Connected Components
|
|
470
539
|
|
|
471
540
|
```typescript
|
|
472
|
-
import {
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
} from
|
|
541
|
+
import {
|
|
542
|
+
stronglyConnectedComponents,
|
|
543
|
+
findStronglyConnectedComponents,
|
|
544
|
+
isStronglyConnected,
|
|
545
|
+
condensationGraph,
|
|
546
|
+
} from "@graphty/algorithms";
|
|
478
547
|
|
|
479
548
|
// Find SCCs using Tarjan's algorithm
|
|
480
549
|
const sccs = stronglyConnectedComponents(graph);
|
|
@@ -500,7 +569,7 @@ const components = connectedComponentsDFS(graph);
|
|
|
500
569
|
#### Weakly Connected Components
|
|
501
570
|
|
|
502
571
|
```typescript
|
|
503
|
-
import { weaklyConnectedComponents, isWeaklyConnected } from
|
|
572
|
+
import { weaklyConnectedComponents, isWeaklyConnected } from "@graphty/algorithms";
|
|
504
573
|
|
|
505
574
|
// Find WCCs (ignoring edge direction)
|
|
506
575
|
const wccs = weaklyConnectedComponents(graph);
|
|
@@ -518,7 +587,7 @@ const weaklyConnected = isWeaklyConnected(graph);
|
|
|
518
587
|
Min-heap implementation used internally by algorithms.
|
|
519
588
|
|
|
520
589
|
```typescript
|
|
521
|
-
import { PriorityQueue } from
|
|
590
|
+
import { PriorityQueue } from "@graphty/algorithms";
|
|
522
591
|
|
|
523
592
|
const pq = new PriorityQueue<T>((a, b) => a.priority - b.priority);
|
|
524
593
|
|
|
@@ -535,7 +604,7 @@ pq.clear();
|
|
|
535
604
|
Efficient data structure for tracking connected components.
|
|
536
605
|
|
|
537
606
|
```typescript
|
|
538
|
-
import { UnionFind } from
|
|
607
|
+
import { UnionFind } from "@graphty/algorithms";
|
|
539
608
|
|
|
540
609
|
const uf = new UnionFind<T>();
|
|
541
610
|
|
|
@@ -552,7 +621,7 @@ uf.numberOfSets;
|
|
|
552
621
|
#### Kruskal's Algorithm
|
|
553
622
|
|
|
554
623
|
```typescript
|
|
555
|
-
import { kruskalMST, minimumSpanningTree } from
|
|
624
|
+
import { kruskalMST, minimumSpanningTree } from "@graphty/algorithms";
|
|
556
625
|
|
|
557
626
|
// Find MST using Kruskal's algorithm
|
|
558
627
|
const mst = kruskalMST(graph);
|
|
@@ -577,12 +646,12 @@ const mst = primMST(graph, startNode?);
|
|
|
577
646
|
#### Louvain Method
|
|
578
647
|
|
|
579
648
|
```typescript
|
|
580
|
-
import { louvain } from
|
|
649
|
+
import { louvain } from "@graphty/algorithms";
|
|
581
650
|
|
|
582
651
|
// Detect communities using Louvain method
|
|
583
652
|
const communities = louvain(graph, {
|
|
584
|
-
|
|
585
|
-
|
|
653
|
+
resolution: number, // Default: 1.0
|
|
654
|
+
randomSeed: number,
|
|
586
655
|
});
|
|
587
656
|
// Returns: { communities: Map<NodeId, number>, modularity: number }
|
|
588
657
|
```
|
|
@@ -590,13 +659,13 @@ const communities = louvain(graph, {
|
|
|
590
659
|
#### Leiden Algorithm
|
|
591
660
|
|
|
592
661
|
```typescript
|
|
593
|
-
import { leiden } from
|
|
662
|
+
import { leiden } from "@graphty/algorithms";
|
|
594
663
|
|
|
595
664
|
// Improved community detection
|
|
596
665
|
const communities = leiden(graph, {
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
666
|
+
resolution: number, // Default: 1.0
|
|
667
|
+
iterations: number, // Default: 10
|
|
668
|
+
randomSeed: number,
|
|
600
669
|
});
|
|
601
670
|
// Returns: { communities: Map<NodeId, number>, modularity: number }
|
|
602
671
|
```
|
|
@@ -604,11 +673,11 @@ const communities = leiden(graph, {
|
|
|
604
673
|
#### Label Propagation
|
|
605
674
|
|
|
606
675
|
```typescript
|
|
607
|
-
import { labelPropagation, labelPropagationAsync, labelPropagationSemiSupervised } from
|
|
676
|
+
import { labelPropagation, labelPropagationAsync, labelPropagationSemiSupervised } from "@graphty/algorithms";
|
|
608
677
|
|
|
609
678
|
// Basic label propagation
|
|
610
679
|
const labels = labelPropagation(graph, {
|
|
611
|
-
|
|
680
|
+
maxIterations: number, // Default: 100
|
|
612
681
|
});
|
|
613
682
|
// Returns: Map<NodeId, number>
|
|
614
683
|
|
|
@@ -622,32 +691,30 @@ const labels = labelPropagationSemiSupervised(graph, seedLabels, options);
|
|
|
622
691
|
#### Girvan-Newman Algorithm
|
|
623
692
|
|
|
624
693
|
```typescript
|
|
625
|
-
import { girvanNewman } from
|
|
694
|
+
import { girvanNewman } from "@graphty/algorithms";
|
|
626
695
|
|
|
627
696
|
// Edge betweenness based community detection
|
|
628
697
|
const dendrogram = girvanNewman(graph, {
|
|
629
|
-
|
|
698
|
+
targetCommunities: number, // Stop at this many communities
|
|
630
699
|
});
|
|
631
700
|
// Returns: { levels: Array<{ modularity: number, communities: NodeId[][] }> }
|
|
632
701
|
```
|
|
633
702
|
|
|
634
703
|
### Pathfinding Algorithms
|
|
635
704
|
|
|
636
|
-
#### A
|
|
705
|
+
#### A\* Algorithm
|
|
637
706
|
|
|
638
707
|
```typescript
|
|
639
|
-
import { astar
|
|
708
|
+
import { astar } from "@graphty/algorithms";
|
|
640
709
|
|
|
641
710
|
// A* pathfinding with heuristic
|
|
642
|
-
const path = astar(
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
//
|
|
647
|
-
|
|
648
|
-
//
|
|
649
|
-
const result = astarWithDetails(graph, start, goal, options);
|
|
650
|
-
// Returns: { path: NodeId[], cost: number, explored: Set<NodeId>, parent: Map<NodeId, NodeId> } | null
|
|
711
|
+
const path = astar(
|
|
712
|
+
graph, // Map<T, Map<T, number>> adjacency list
|
|
713
|
+
start,
|
|
714
|
+
goal,
|
|
715
|
+
heuristic, // (node: T, goal: T) => number
|
|
716
|
+
);
|
|
717
|
+
// Returns: { path: T[], cost: number } | null
|
|
651
718
|
```
|
|
652
719
|
|
|
653
720
|
### Flow Algorithms
|
|
@@ -694,7 +761,7 @@ const cut = kargerMinCut(graph, iterations?);
|
|
|
694
761
|
#### Hierarchical Clustering
|
|
695
762
|
|
|
696
763
|
```typescript
|
|
697
|
-
import { hierarchicalClustering, cutDendrogram, cutDendrogramKClusters } from
|
|
764
|
+
import { hierarchicalClustering, cutDendrogram, cutDendrogramKClusters } from "@graphty/algorithms";
|
|
698
765
|
|
|
699
766
|
// Agglomerative clustering
|
|
700
767
|
const result = hierarchicalClustering(graph, linkage);
|
|
@@ -714,7 +781,7 @@ const clusters = cutDendrogramKClusters(result.root, k);
|
|
|
714
781
|
#### K-Core Decomposition
|
|
715
782
|
|
|
716
783
|
```typescript
|
|
717
|
-
import { kCoreDecomposition, getKCore, kTruss, degeneracyOrdering } from
|
|
784
|
+
import { kCoreDecomposition, getKCore, kTruss, degeneracyOrdering } from "@graphty/algorithms";
|
|
718
785
|
|
|
719
786
|
// Find all k-cores
|
|
720
787
|
const result = kCoreDecomposition(graph);
|
|
@@ -737,14 +804,14 @@ const ordering = degeneracyOrdering(graph);
|
|
|
737
804
|
#### Spectral Clustering
|
|
738
805
|
|
|
739
806
|
```typescript
|
|
740
|
-
import { spectralClustering } from
|
|
807
|
+
import { spectralClustering } from "@graphty/algorithms";
|
|
741
808
|
|
|
742
809
|
// Spectral clustering using graph Laplacian
|
|
743
810
|
const result = spectralClustering(graph, {
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
811
|
+
k: number, // Number of clusters
|
|
812
|
+
laplacianType: "unnormalized" | "normalized" | "randomWalk", // Default: 'normalized'
|
|
813
|
+
maxIterations: number, // Default: 100
|
|
814
|
+
tolerance: number, // Default: 1e-4
|
|
748
815
|
});
|
|
749
816
|
// Returns: SpectralClusteringResult { communities: NodeId[][], clusterAssignments: Map<NodeId, number> }
|
|
750
817
|
```
|
|
@@ -752,16 +819,20 @@ const result = spectralClustering(graph, {
|
|
|
752
819
|
#### Markov Clustering (MCL)
|
|
753
820
|
|
|
754
821
|
```typescript
|
|
755
|
-
import { markovClustering } from
|
|
822
|
+
import { markovClustering, calculateMCLModularity } from "@graphty/algorithms";
|
|
756
823
|
|
|
757
824
|
// MCL algorithm for network clustering
|
|
758
825
|
const result = markovClustering(graph, {
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
826
|
+
expansion: number, // Expansion parameter (default: 2)
|
|
827
|
+
inflation: number, // Inflation parameter (default: 2)
|
|
828
|
+
maxIterations: number, // Default: 100
|
|
829
|
+
tolerance: number, // Default: 1e-6
|
|
763
830
|
});
|
|
764
831
|
// Returns: MCLResult { communities: NodeId[][], attractors: Set<NodeId>, iterations: number, converged: boolean }
|
|
832
|
+
|
|
833
|
+
// Calculate modularity of MCL clustering result
|
|
834
|
+
const modularity = calculateMCLModularity(graph, result.communities);
|
|
835
|
+
// Returns: number
|
|
765
836
|
```
|
|
766
837
|
|
|
767
838
|
### Matching Algorithms
|
|
@@ -769,12 +840,12 @@ const result = markovClustering(graph, {
|
|
|
769
840
|
#### Bipartite Matching
|
|
770
841
|
|
|
771
842
|
```typescript
|
|
772
|
-
import { maximumBipartiteMatching, greedyBipartiteMatching, bipartitePartition } from
|
|
843
|
+
import { maximumBipartiteMatching, greedyBipartiteMatching, bipartitePartition } from "@graphty/algorithms";
|
|
773
844
|
|
|
774
845
|
// Maximum bipartite matching (Hungarian algorithm)
|
|
775
846
|
const matching = maximumBipartiteMatching(graph, {
|
|
776
|
-
|
|
777
|
-
|
|
847
|
+
leftNodes: Set<NodeId>, // Optional: specify left partition
|
|
848
|
+
rightNodes: Set<NodeId>, // Optional: specify right partition
|
|
778
849
|
});
|
|
779
850
|
// Returns: BipartiteMatchingResult { matching: Map<NodeId, NodeId>, size: number }
|
|
780
851
|
|
|
@@ -789,13 +860,13 @@ const partition = bipartitePartition(graph);
|
|
|
789
860
|
#### Graph Isomorphism
|
|
790
861
|
|
|
791
862
|
```typescript
|
|
792
|
-
import { isGraphIsomorphic, findAllIsomorphisms } from
|
|
863
|
+
import { isGraphIsomorphic, findAllIsomorphisms } from "@graphty/algorithms";
|
|
793
864
|
|
|
794
865
|
// Check if two graphs are isomorphic
|
|
795
866
|
const result = isGraphIsomorphic(graph1, graph2, {
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
867
|
+
nodeMatch: (node1: NodeId, node2: NodeId, g1: Graph, g2: Graph) => boolean,
|
|
868
|
+
edgeMatch: (edge1: [NodeId, NodeId], edge2: [NodeId, NodeId], g1: Graph, g2: Graph) => boolean,
|
|
869
|
+
findAllMappings: boolean, // Find all possible isomorphisms
|
|
799
870
|
});
|
|
800
871
|
// Returns: IsomorphismResult { isIsomorphic: boolean, mapping?: Map<NodeId, NodeId> }
|
|
801
872
|
|
|
@@ -809,7 +880,7 @@ const mappings = findAllIsomorphisms(graph1, graph2, options);
|
|
|
809
880
|
#### Common Neighbors
|
|
810
881
|
|
|
811
882
|
```typescript
|
|
812
|
-
import { commonNeighborsScore, commonNeighborsPrediction, commonNeighborsForPairs } from
|
|
883
|
+
import { commonNeighborsScore, commonNeighborsPrediction, commonNeighborsForPairs } from "@graphty/algorithms";
|
|
813
884
|
|
|
814
885
|
// Score for a specific pair
|
|
815
886
|
const score = commonNeighborsScore(graph, node1, node2);
|
|
@@ -817,9 +888,9 @@ const score = commonNeighborsScore(graph, node1, node2);
|
|
|
817
888
|
|
|
818
889
|
// Predict links for all non-connected pairs
|
|
819
890
|
const predictions = commonNeighborsPrediction(graph, {
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
891
|
+
directed: boolean, // Consider direction
|
|
892
|
+
includeExisting: boolean, // Include existing edges
|
|
893
|
+
topK: number, // Return only top K predictions
|
|
823
894
|
});
|
|
824
895
|
// Returns: LinkPredictionScore[]
|
|
825
896
|
|
|
@@ -832,14 +903,14 @@ const evaluation = evaluateCommonNeighbors(graph, testEdges);
|
|
|
832
903
|
// Returns: { precision, recall, f1Score }
|
|
833
904
|
|
|
834
905
|
// Get top candidates for a node
|
|
835
|
-
const candidates = getTopCandidatesForNode(graph, nodeId, { topK
|
|
906
|
+
const candidates = getTopCandidatesForNode(graph, nodeId, { topK: number });
|
|
836
907
|
// Returns: LinkPredictionScore[]
|
|
837
908
|
```
|
|
838
909
|
|
|
839
910
|
#### Adamic-Adar Index
|
|
840
911
|
|
|
841
912
|
```typescript
|
|
842
|
-
import { adamicAdarScore, adamicAdarPrediction, adamicAdarForPairs } from
|
|
913
|
+
import { adamicAdarScore, adamicAdarPrediction, adamicAdarForPairs } from "@graphty/algorithms";
|
|
843
914
|
|
|
844
915
|
// Adamic-Adar score for a pair (weighted by neighbor degrees)
|
|
845
916
|
const score = adamicAdarScore(graph, node1, node2);
|
|
@@ -847,9 +918,9 @@ const score = adamicAdarScore(graph, node1, node2);
|
|
|
847
918
|
|
|
848
919
|
// Predict links using Adamic-Adar
|
|
849
920
|
const predictions = adamicAdarPrediction(graph, {
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
921
|
+
directed: boolean,
|
|
922
|
+
includeExisting: boolean,
|
|
923
|
+
topK: number,
|
|
853
924
|
});
|
|
854
925
|
// Returns: LinkPredictionScore[]
|
|
855
926
|
|
|
@@ -866,7 +937,9 @@ const evaluation = evaluateAdamicAdar(graph, testEdges);
|
|
|
866
937
|
// Returns: { precision, recall, f1Score }
|
|
867
938
|
|
|
868
939
|
// Get top candidates for a node
|
|
869
|
-
const candidates = getTopAdamicAdarCandidatesForNode(graph, nodeId, {
|
|
940
|
+
const candidates = getTopAdamicAdarCandidatesForNode(graph, nodeId, {
|
|
941
|
+
topK: number,
|
|
942
|
+
});
|
|
870
943
|
// Returns: LinkPredictionScore[]
|
|
871
944
|
```
|
|
872
945
|
|
|
@@ -877,18 +950,18 @@ Cutting-edge graph algorithms based on recent research.
|
|
|
877
950
|
#### SynC - Synergistic Deep Graph Clustering
|
|
878
951
|
|
|
879
952
|
```typescript
|
|
880
|
-
import { syncClustering } from
|
|
953
|
+
import { syncClustering } from "@graphty/algorithms";
|
|
881
954
|
|
|
882
955
|
// Deep learning based clustering
|
|
883
956
|
const result = syncClustering(graph, {
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
957
|
+
k: number, // Number of clusters
|
|
958
|
+
maxIterations: number, // Default: 100
|
|
959
|
+
learningRate: number, // Default: 0.01
|
|
960
|
+
hiddenDim: number, // Default: 64
|
|
961
|
+
randomSeed: number,
|
|
889
962
|
});
|
|
890
|
-
// Returns: SynCResult {
|
|
891
|
-
// communities: NodeId[][],
|
|
963
|
+
// Returns: SynCResult {
|
|
964
|
+
// communities: NodeId[][],
|
|
892
965
|
// clusterAssignments: Map<NodeId, number>,
|
|
893
966
|
// embeddings: Map<NodeId, number[]>,
|
|
894
967
|
// iterations: number,
|
|
@@ -899,15 +972,15 @@ const result = syncClustering(graph, {
|
|
|
899
972
|
#### TeraHAC - Scalable Hierarchical Agglomerative Clustering
|
|
900
973
|
|
|
901
974
|
```typescript
|
|
902
|
-
import { teraHAC } from
|
|
975
|
+
import { teraHAC } from "@graphty/algorithms";
|
|
903
976
|
|
|
904
977
|
// Scalable hierarchical clustering
|
|
905
978
|
const result = teraHAC(graph, {
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
979
|
+
linkage: "single" | "complete" | "average", // Default: 'average'
|
|
980
|
+
k: number, // Target number of clusters
|
|
981
|
+
threshold: number, // Distance threshold for merging
|
|
982
|
+
sampleSize: number, // Default: 1000
|
|
983
|
+
randomSeed: number,
|
|
911
984
|
});
|
|
912
985
|
// Returns: TeraHACResult {
|
|
913
986
|
// root: TeraHACClusterNode,
|
|
@@ -920,14 +993,14 @@ const result = teraHAC(graph, {
|
|
|
920
993
|
#### GRSBM - Greedy Recursive Spectral Bisection with Modularity
|
|
921
994
|
|
|
922
995
|
```typescript
|
|
923
|
-
import { grsbm } from
|
|
996
|
+
import { grsbm } from "@graphty/algorithms";
|
|
924
997
|
|
|
925
998
|
// Explainable community detection
|
|
926
999
|
const result = grsbm(graph, {
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
1000
|
+
minClusterSize: number, // Default: 5
|
|
1001
|
+
maxDepth: number, // Default: 10
|
|
1002
|
+
modularityThreshold: number, // Default: 0.1
|
|
1003
|
+
explainClusters: boolean, // Default: true
|
|
931
1004
|
});
|
|
932
1005
|
// Returns: GRSBMResult {
|
|
933
1006
|
// clusters: GRSBMCluster[], // Each cluster has id, nodes, modularity, explanation
|
|
@@ -941,7 +1014,7 @@ const result = grsbm(graph, {
|
|
|
941
1014
|
### Available Algorithms by Category:
|
|
942
1015
|
|
|
943
1016
|
- **Traversal**: BFS, DFS, Topological Sort, Cycle Detection, Bipartite Check
|
|
944
|
-
- **Shortest Path**: Dijkstra, Bellman-Ford, Floyd-Warshall, A
|
|
1017
|
+
- **Shortest Path**: Dijkstra, Bellman-Ford, Floyd-Warshall, A\*
|
|
945
1018
|
- **Centrality**: Degree, Betweenness, Closeness, PageRank, Eigenvector, Katz, HITS
|
|
946
1019
|
- **Components**: Connected, Strongly Connected, Weakly Connected, Condensation Graph
|
|
947
1020
|
- **Community Detection**: Louvain, Leiden, Label Propagation, Girvan-Newman
|
|
@@ -952,11 +1025,18 @@ const result = grsbm(graph, {
|
|
|
952
1025
|
- **Link Prediction**: Common Neighbors, Adamic-Adar
|
|
953
1026
|
- **Research Algorithms**: SynC, TeraHAC, GRSBM
|
|
954
1027
|
|
|
955
|
-
## Examples
|
|
1028
|
+
## Interactive Examples
|
|
1029
|
+
|
|
1030
|
+
Try out all algorithms with interactive visualizations: **[Live Demo →](https://graphty-org.github.io/algorithms/)**
|
|
956
1031
|
|
|
957
|
-
The library includes comprehensive examples demonstrating each algorithm.
|
|
1032
|
+
The library includes comprehensive examples demonstrating each algorithm. You can:
|
|
1033
|
+
|
|
1034
|
+
- **[Browse Interactive HTML Examples](https://graphty-org.github.io/algorithms/examples/)** - Visual demonstrations with step-by-step execution
|
|
1035
|
+
- **[View Performance Benchmarks](https://graphty-org.github.io/algorithms/benchmarks/)** - Comparative analysis of algorithm performance
|
|
1036
|
+
- **[Explore Code Examples](https://github.com/graphty-org/algorithms/tree/main/examples)** - Implementation examples for each algorithm
|
|
958
1037
|
|
|
959
1038
|
### Basic Algorithms
|
|
1039
|
+
|
|
960
1040
|
- [BFS Traversal](https://github.com/graphty-org/algorithms/blob/main/examples/bfs-example.js) - Breadth-first search and shortest paths
|
|
961
1041
|
- [DFS Traversal](https://github.com/graphty-org/algorithms/blob/main/examples/dfs-example.js) - Depth-first search and applications
|
|
962
1042
|
- [Dijkstra's Algorithm](https://github.com/graphty-org/algorithms/blob/main/examples/dijkstra-example.js) - Weighted shortest paths
|
|
@@ -964,6 +1044,7 @@ The library includes comprehensive examples demonstrating each algorithm. Find t
|
|
|
964
1044
|
- [Floyd-Warshall](https://github.com/graphty-org/algorithms/blob/main/examples/floyd-warshall-example.js) - All pairs shortest paths
|
|
965
1045
|
|
|
966
1046
|
### Centrality Measures
|
|
1047
|
+
|
|
967
1048
|
- [Degree Centrality](https://github.com/graphty-org/algorithms/blob/main/examples/degree-centrality-example.js) - Node importance by connections
|
|
968
1049
|
- [Betweenness Centrality](https://github.com/graphty-org/algorithms/blob/main/examples/betweenness-centrality-example.js) - Bridge nodes
|
|
969
1050
|
- [Closeness Centrality](https://github.com/graphty-org/algorithms/blob/main/examples/closeness-centrality-example.js) - Central nodes
|
|
@@ -973,37 +1054,44 @@ The library includes comprehensive examples demonstrating each algorithm. Find t
|
|
|
973
1054
|
- [HITS Algorithm](https://github.com/graphty-org/algorithms/blob/main/examples/hits-algorithm-example.js) - Hub and authority scores
|
|
974
1055
|
|
|
975
1056
|
### Graph Structure
|
|
1057
|
+
|
|
976
1058
|
- [Connected Components](https://github.com/graphty-org/algorithms/blob/main/examples/connected-components-example.js) - Find graph components
|
|
977
1059
|
- [Kruskal's MST](https://github.com/graphty-org/algorithms/blob/main/examples/kruskal-example.js) - Minimum spanning tree
|
|
978
1060
|
- [Prim's MST](https://github.com/graphty-org/algorithms/blob/main/examples/prim-example.js) - Alternative MST algorithm
|
|
979
1061
|
|
|
980
1062
|
### Community Detection
|
|
1063
|
+
|
|
981
1064
|
- [Louvain Method](https://github.com/graphty-org/algorithms/blob/main/examples/louvain-example.js) - Modularity-based communities
|
|
982
1065
|
- [Leiden Algorithm](https://github.com/graphty-org/algorithms/blob/main/examples/leiden-community.ts) - Improved Louvain
|
|
983
1066
|
- [Label Propagation](https://github.com/graphty-org/algorithms/blob/main/examples/label-propagation.ts) - Fast community detection
|
|
984
1067
|
- [Girvan-Newman](https://github.com/graphty-org/algorithms/blob/main/examples/girvan-newman-example.js) - Hierarchical communities
|
|
985
1068
|
|
|
986
1069
|
### Clustering
|
|
1070
|
+
|
|
987
1071
|
- [Hierarchical Clustering](https://github.com/graphty-org/algorithms/blob/main/examples/hierarchical-clustering.ts) - Graph clustering
|
|
988
1072
|
- [K-Core Decomposition](https://github.com/graphty-org/algorithms/blob/main/examples/k-core-decomposition.ts) - Core analysis
|
|
989
1073
|
- [Spectral Clustering](https://github.com/graphty-org/algorithms/blob/main/examples/spectral-clustering-example.js) - Eigenvalue-based clustering
|
|
990
1074
|
- [MCL Clustering](https://github.com/graphty-org/algorithms/blob/main/examples/mcl-clustering-example.js) - Markov clustering
|
|
991
1075
|
|
|
992
1076
|
### Matching
|
|
1077
|
+
|
|
993
1078
|
- [Bipartite Matching](https://github.com/graphty-org/algorithms/blob/main/examples/bipartite-matching-example.js) - Job assignment, dating apps
|
|
994
1079
|
- [Graph Isomorphism](https://github.com/graphty-org/algorithms/blob/main/examples/graph-isomorphism-example.js) - Structural equivalence
|
|
995
1080
|
|
|
996
1081
|
### Link Prediction
|
|
1082
|
+
|
|
997
1083
|
- [Common Neighbors](https://github.com/graphty-org/algorithms/blob/main/examples/common-neighbors-example.js) - Friend suggestions
|
|
998
1084
|
- [Adamic-Adar](https://github.com/graphty-org/algorithms/blob/main/examples/adamic-adar-example.js) - Weighted predictions
|
|
999
1085
|
|
|
1000
1086
|
### Advanced Algorithms
|
|
1001
|
-
|
|
1087
|
+
|
|
1088
|
+
- [A\* Pathfinding](https://github.com/graphty-org/algorithms/blob/main/examples/astar-pathfinding.ts) - Heuristic pathfinding
|
|
1002
1089
|
- [Flow Algorithms](https://github.com/graphty-org/algorithms/blob/main/examples/flow-algorithms.ts) - Maximum flow and applications
|
|
1003
1090
|
- [Ford-Fulkerson Flow](https://github.com/graphty-org/algorithms/blob/main/examples/ford-fulkerson-flow.ts) - Maximum flow implementation
|
|
1004
1091
|
- [Minimum Cut](https://github.com/graphty-org/algorithms/blob/main/examples/min-cut.ts) - Graph partitioning
|
|
1005
1092
|
|
|
1006
1093
|
### Research Algorithms
|
|
1094
|
+
|
|
1007
1095
|
- [SynC Clustering](https://github.com/graphty-org/algorithms/blob/main/examples/sync-example.js) - Deep learning based clustering
|
|
1008
1096
|
- [TeraHAC](https://github.com/graphty-org/algorithms/blob/main/examples/terahac-example.js) - Scalable hierarchical clustering
|
|
1009
1097
|
- [GRSBM](https://github.com/graphty-org/algorithms/blob/main/examples/grsbm-example.js) - Explainable community detection
|
|
@@ -1016,13 +1104,13 @@ The library includes comprehensive examples demonstrating each algorithm. Find t
|
|
|
1016
1104
|
const graph = new Graph();
|
|
1017
1105
|
|
|
1018
1106
|
// Add weighted edges
|
|
1019
|
-
graph.addEdge(
|
|
1020
|
-
graph.addEdge(
|
|
1021
|
-
graph.addEdge(
|
|
1107
|
+
graph.addEdge("A", "B", 5);
|
|
1108
|
+
graph.addEdge("B", "C", 3);
|
|
1109
|
+
graph.addEdge("A", "C", 10);
|
|
1022
1110
|
|
|
1023
1111
|
// Find shortest path considering weights
|
|
1024
|
-
const result = dijkstra(graph,
|
|
1025
|
-
const pathToC = dijkstraPath(graph,
|
|
1112
|
+
const result = dijkstra(graph, "A");
|
|
1113
|
+
const pathToC = dijkstraPath(graph, "A", "C");
|
|
1026
1114
|
console.log(pathToC); // { path: ['A', 'B', 'C'], distance: 8 }
|
|
1027
1115
|
```
|
|
1028
1116
|
|
|
@@ -1031,9 +1119,9 @@ console.log(pathToC); // { path: ['A', 'B', 'C'], distance: 8 }
|
|
|
1031
1119
|
```typescript
|
|
1032
1120
|
const directedGraph = new Graph({ directed: true });
|
|
1033
1121
|
|
|
1034
|
-
directedGraph.addEdge(
|
|
1035
|
-
directedGraph.addEdge(
|
|
1036
|
-
directedGraph.addEdge(
|
|
1122
|
+
directedGraph.addEdge("A", "B");
|
|
1123
|
+
directedGraph.addEdge("B", "C");
|
|
1124
|
+
directedGraph.addEdge("C", "A");
|
|
1037
1125
|
|
|
1038
1126
|
// Check for cycles
|
|
1039
1127
|
console.log(hasCycleDFS(directedGraph)); // true
|
|
@@ -1054,8 +1142,8 @@ const influencers = topPageRankNodes(graph, 10);
|
|
|
1054
1142
|
|
|
1055
1143
|
// Find bridges (high betweenness)
|
|
1056
1144
|
const bridgers = Array.from(betweennessCentrality(graph).entries())
|
|
1057
|
-
|
|
1058
|
-
|
|
1145
|
+
.sort((a, b) => b[1] - a[1])
|
|
1146
|
+
.slice(0, 10);
|
|
1059
1147
|
|
|
1060
1148
|
// Find communities (connected components)
|
|
1061
1149
|
const communities = connectedComponents(graph);
|
|
@@ -1068,15 +1156,15 @@ console.log(`Found ${communities.components.length} communities`);
|
|
|
1068
1156
|
const graph = new Graph();
|
|
1069
1157
|
|
|
1070
1158
|
// Add edges with custom data
|
|
1071
|
-
graph.addEdge(
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1159
|
+
graph.addEdge("A", "B", 1, {
|
|
1160
|
+
type: "road",
|
|
1161
|
+
distance: 100,
|
|
1162
|
+
traffic: "heavy",
|
|
1075
1163
|
});
|
|
1076
1164
|
|
|
1077
1165
|
// Use custom weight in algorithms
|
|
1078
|
-
const result = dijkstra(graph,
|
|
1079
|
-
|
|
1166
|
+
const result = dijkstra(graph, "A", {
|
|
1167
|
+
weightKey: "distance", // Use 'distance' property as weight
|
|
1080
1168
|
});
|
|
1081
1169
|
```
|
|
1082
1170
|
|
|
@@ -1091,18 +1179,18 @@ const centralities = degreeCentrality(graph, { normalized: true });
|
|
|
1091
1179
|
const ranks = pageRank(graph);
|
|
1092
1180
|
|
|
1093
1181
|
// Export for visualization
|
|
1094
|
-
const nodes = Array.from(graph.nodes()).map(node => ({
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1182
|
+
const nodes = Array.from(graph.nodes()).map((node) => ({
|
|
1183
|
+
id: node.id,
|
|
1184
|
+
data: node.data,
|
|
1185
|
+
size: centralities.get(node.id) || 0,
|
|
1186
|
+
importance: ranks.get(node.id) || 0,
|
|
1099
1187
|
}));
|
|
1100
1188
|
|
|
1101
|
-
const edges = Array.from(graph.edges()).map(edge => ({
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1189
|
+
const edges = Array.from(graph.edges()).map((edge) => ({
|
|
1190
|
+
source: edge.source,
|
|
1191
|
+
target: edge.target,
|
|
1192
|
+
weight: edge.weight || 1,
|
|
1193
|
+
data: edge.data,
|
|
1106
1194
|
}));
|
|
1107
1195
|
```
|
|
1108
1196
|
|
|
@@ -1114,16 +1202,16 @@ const edges = Array.from(graph.edges()).map(edge => ({
|
|
|
1114
1202
|
type NodeId = string | number;
|
|
1115
1203
|
|
|
1116
1204
|
interface Node {
|
|
1117
|
-
|
|
1118
|
-
|
|
1205
|
+
id: NodeId;
|
|
1206
|
+
data?: Record<string, unknown>;
|
|
1119
1207
|
}
|
|
1120
1208
|
|
|
1121
1209
|
interface Edge {
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1210
|
+
source: NodeId;
|
|
1211
|
+
target: NodeId;
|
|
1212
|
+
weight?: number;
|
|
1213
|
+
id?: string;
|
|
1214
|
+
data?: Record<string, unknown>;
|
|
1127
1215
|
}
|
|
1128
1216
|
```
|
|
1129
1217
|
|
|
@@ -1131,106 +1219,106 @@ interface Edge {
|
|
|
1131
1219
|
|
|
1132
1220
|
```typescript
|
|
1133
1221
|
interface TraversalResult {
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1222
|
+
visited: Set<NodeId>;
|
|
1223
|
+
order: NodeId[];
|
|
1224
|
+
tree?: Map<NodeId, NodeId | null>;
|
|
1137
1225
|
}
|
|
1138
1226
|
|
|
1139
1227
|
interface ShortestPathResult {
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1228
|
+
distance: number;
|
|
1229
|
+
path: NodeId[];
|
|
1230
|
+
predecessor: Map<NodeId, NodeId | null>;
|
|
1143
1231
|
}
|
|
1144
1232
|
|
|
1145
1233
|
interface BellmanFordResult {
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1234
|
+
distances: Map<NodeId, number>;
|
|
1235
|
+
previous: Map<NodeId, NodeId | null>;
|
|
1236
|
+
hasNegativeCycle: boolean;
|
|
1237
|
+
negativeCycleNodes?: NodeId[];
|
|
1150
1238
|
}
|
|
1151
1239
|
|
|
1152
1240
|
type CentralityResult = Record<string, number>;
|
|
1153
1241
|
|
|
1154
1242
|
interface PageRankResult {
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1243
|
+
ranks: Record<string, number>;
|
|
1244
|
+
iterations: number;
|
|
1245
|
+
converged: boolean;
|
|
1158
1246
|
}
|
|
1159
1247
|
|
|
1160
1248
|
interface CommunityResult {
|
|
1161
|
-
|
|
1162
|
-
|
|
1249
|
+
communities: Map<NodeId, number>;
|
|
1250
|
+
modularity: number;
|
|
1163
1251
|
}
|
|
1164
1252
|
|
|
1165
1253
|
interface ComponentResult {
|
|
1166
|
-
|
|
1167
|
-
|
|
1254
|
+
components: NodeId[][];
|
|
1255
|
+
componentMap: Map<NodeId, number>;
|
|
1168
1256
|
}
|
|
1169
1257
|
|
|
1170
1258
|
interface HITSResult {
|
|
1171
|
-
|
|
1172
|
-
|
|
1259
|
+
hubs: CentralityResult;
|
|
1260
|
+
authorities: CentralityResult;
|
|
1173
1261
|
}
|
|
1174
1262
|
|
|
1175
1263
|
interface SpectralClusteringResult {
|
|
1176
|
-
|
|
1177
|
-
|
|
1264
|
+
communities: NodeId[][];
|
|
1265
|
+
clusterAssignments: Map<NodeId, number>;
|
|
1178
1266
|
}
|
|
1179
1267
|
|
|
1180
1268
|
interface MCLResult {
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1269
|
+
communities: NodeId[][];
|
|
1270
|
+
attractors: Set<NodeId>;
|
|
1271
|
+
iterations: number;
|
|
1272
|
+
converged: boolean;
|
|
1185
1273
|
}
|
|
1186
1274
|
|
|
1187
1275
|
interface BipartiteMatchingResult {
|
|
1188
|
-
|
|
1189
|
-
|
|
1276
|
+
matching: Map<NodeId, NodeId>;
|
|
1277
|
+
size: number;
|
|
1190
1278
|
}
|
|
1191
1279
|
|
|
1192
1280
|
interface LinkPredictionScore {
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1281
|
+
source: NodeId;
|
|
1282
|
+
target: NodeId;
|
|
1283
|
+
score: number;
|
|
1196
1284
|
}
|
|
1197
1285
|
|
|
1198
1286
|
interface HierarchicalClusteringResult<T> {
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1287
|
+
root: ClusterNode<T>;
|
|
1288
|
+
dendrogram: ClusterNode<T>[];
|
|
1289
|
+
clusters: Map<number, Set<T>[]>;
|
|
1202
1290
|
}
|
|
1203
1291
|
|
|
1204
1292
|
interface KCoreResult<T> {
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1293
|
+
cores: Map<number, Set<T>>;
|
|
1294
|
+
coreness: Map<T, number>;
|
|
1295
|
+
maxCore: number;
|
|
1208
1296
|
}
|
|
1209
1297
|
|
|
1210
1298
|
interface IsomorphismResult {
|
|
1211
|
-
|
|
1212
|
-
|
|
1299
|
+
isIsomorphic: boolean;
|
|
1300
|
+
mapping?: Map<NodeId, NodeId>;
|
|
1213
1301
|
}
|
|
1214
1302
|
|
|
1215
1303
|
interface SynCResult {
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1304
|
+
communities: NodeId[][];
|
|
1305
|
+
clusterAssignments: Map<NodeId, number>;
|
|
1306
|
+
embeddings: Map<NodeId, number[]>;
|
|
1307
|
+
iterations: number;
|
|
1308
|
+
converged: boolean;
|
|
1221
1309
|
}
|
|
1222
1310
|
|
|
1223
1311
|
interface TeraHACResult {
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1312
|
+
root: TeraHACClusterNode;
|
|
1313
|
+
dendrogram: TeraHACClusterNode[];
|
|
1314
|
+
clusters: NodeId[][];
|
|
1315
|
+
mergeDistances: number[];
|
|
1228
1316
|
}
|
|
1229
1317
|
|
|
1230
1318
|
interface GRSBMResult {
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1319
|
+
clusters: GRSBMCluster[];
|
|
1320
|
+
hierarchy: Map<number, number[]>;
|
|
1321
|
+
totalModularity: number;
|
|
1234
1322
|
}
|
|
1235
1323
|
```
|
|
1236
1324
|
|
|
@@ -1238,30 +1326,31 @@ interface GRSBMResult {
|
|
|
1238
1326
|
|
|
1239
1327
|
- **Graph Representation**: Uses adjacency lists for O(1) neighbor access
|
|
1240
1328
|
- **Algorithm Complexity**:
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1329
|
+
- BFS/DFS: O(V + E)
|
|
1330
|
+
- Dijkstra: O((V + E) log V) with binary heap
|
|
1331
|
+
- Bellman-Ford: O(VE)
|
|
1332
|
+
- Floyd-Warshall: O(V³)
|
|
1333
|
+
- PageRank: O(k(V + E)) where k is iterations
|
|
1334
|
+
- Connected Components: O(V + E)
|
|
1335
|
+
- Kruskal's MST: O(E log E)
|
|
1336
|
+
- Prim's MST: O((V + E) log V)
|
|
1337
|
+
- A\*: O((V + E) log V) - depends on heuristic quality
|
|
1338
|
+
- Ford-Fulkerson: O(E \* f) where f is max flow
|
|
1339
|
+
- Edmonds-Karp: O(VE²)
|
|
1340
|
+
- Louvain/Leiden: O(n log n) average case
|
|
1341
|
+
- Hierarchical Clustering: O(n² log n)
|
|
1342
|
+
- SynC: O(kni) where k is clusters, n is nodes, i is iterations
|
|
1343
|
+
- TeraHAC: O(n log n) with sampling
|
|
1344
|
+
- GRSBM: O(m log n) where m is edges
|
|
1257
1345
|
- **Memory Usage**: O(V + E) for graph storage
|
|
1258
1346
|
- **Browser Optimization**: Algorithms use iterative approaches where possible to avoid stack overflow
|
|
1347
|
+
- **Performance Benchmarks**: View detailed performance comparisons at [https://graphty-org.github.io/algorithms/benchmarks/](https://graphty-org.github.io/algorithms/benchmarks/)
|
|
1259
1348
|
|
|
1260
1349
|
## Development
|
|
1261
1350
|
|
|
1262
1351
|
### Prerequisites
|
|
1263
1352
|
|
|
1264
|
-
- Node.js 18+
|
|
1353
|
+
- Node.js 18+
|
|
1265
1354
|
- npm 9+
|
|
1266
1355
|
|
|
1267
1356
|
### Setup
|
|
@@ -1297,12 +1386,18 @@ npm run lint # Run ESLint
|
|
|
1297
1386
|
npm run lint:fix # Fix ESLint issues
|
|
1298
1387
|
npm run lint:pkg # Check for unused dependencies
|
|
1299
1388
|
|
|
1300
|
-
#
|
|
1301
|
-
npm run
|
|
1389
|
+
# Benchmarking
|
|
1390
|
+
npm run benchmark # Run full benchmark suite
|
|
1391
|
+
npm run benchmark:quick # Run quick benchmark
|
|
1392
|
+
npm run benchmark:report # Generate performance report
|
|
1302
1393
|
|
|
1303
|
-
# HTML Examples
|
|
1304
|
-
npm run examples:html # Run interactive HTML examples
|
|
1394
|
+
# HTML Examples & Documentation
|
|
1395
|
+
npm run examples:html # Run interactive HTML examples locally
|
|
1305
1396
|
npm run build:gh-pages # Build for GitHub Pages deployment
|
|
1397
|
+
npm run examples:run # Run all code examples
|
|
1398
|
+
|
|
1399
|
+
# Git
|
|
1400
|
+
npm run commit # Conventional commit helper
|
|
1306
1401
|
```
|
|
1307
1402
|
|
|
1308
1403
|
### Development Server
|
|
@@ -1310,30 +1405,34 @@ npm run build:gh-pages # Build for GitHub Pages deployment
|
|
|
1310
1405
|
The project includes interactive HTML examples demonstrating each algorithm. To run them locally:
|
|
1311
1406
|
|
|
1312
1407
|
1. **Copy the environment configuration:**
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1408
|
+
|
|
1409
|
+
```bash
|
|
1410
|
+
cp .env.example .env
|
|
1411
|
+
```
|
|
1316
1412
|
|
|
1317
1413
|
2. **Configure the server (optional):**
|
|
1318
1414
|
Edit `.env` to set your preferred host and port:
|
|
1319
|
-
```bash
|
|
1320
|
-
# Server host (defaults to true for network exposure)
|
|
1321
|
-
HOST=localhost # For local-only access
|
|
1322
|
-
# HOST=0.0.0.0 # For network access
|
|
1323
|
-
# HOST=my.server.com # Custom domain
|
|
1324
1415
|
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1416
|
+
```bash
|
|
1417
|
+
# Server host (defaults to true for network exposure)
|
|
1418
|
+
HOST=localhost # For local-only access
|
|
1419
|
+
# HOST=0.0.0.0 # For network access
|
|
1420
|
+
# HOST=my.server.com # Custom domain
|
|
1421
|
+
|
|
1422
|
+
# Server port (defaults to 9000)
|
|
1423
|
+
PORT=9000 # Must be between 9000-9099
|
|
1424
|
+
```
|
|
1328
1425
|
|
|
1329
1426
|
3. **Start the development server:**
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1427
|
+
|
|
1428
|
+
```bash
|
|
1429
|
+
npm run examples:html
|
|
1430
|
+
```
|
|
1333
1431
|
|
|
1334
1432
|
4. **Open your browser** to `http://localhost:9000` (or your configured host/port)
|
|
1335
1433
|
|
|
1336
1434
|
The HTML examples provide:
|
|
1435
|
+
|
|
1337
1436
|
- Interactive visualizations for each algorithm
|
|
1338
1437
|
- Step-by-step execution with play/pause controls
|
|
1339
1438
|
- Multiple graph types for testing
|