@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
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type {Graph} from "../../core/graph.js";
|
|
2
|
-
import type {NodeId} from "../../types/index.js";
|
|
1
|
+
import type { Graph } from "../../core/graph.js";
|
|
2
|
+
import type { NodeId } from "../../types/index.js";
|
|
3
|
+
import { SimpleDeltaPageRank } from "./delta-pagerank-simple.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* PageRank algorithm implementation
|
|
@@ -36,6 +37,12 @@ export interface PageRankOptions {
|
|
|
36
37
|
* Weight attribute for weighted PageRank (default: null = unweighted)
|
|
37
38
|
*/
|
|
38
39
|
weight?: string;
|
|
40
|
+
/**
|
|
41
|
+
* Use delta-based optimization for faster convergence.
|
|
42
|
+
* Defaults to true for graphs with >100 nodes, false for smaller graphs.
|
|
43
|
+
* Set explicitly to override automatic heuristic.
|
|
44
|
+
*/
|
|
45
|
+
useDelta?: boolean;
|
|
39
46
|
}
|
|
40
47
|
|
|
41
48
|
/**
|
|
@@ -58,11 +65,22 @@ export interface PageRankResult {
|
|
|
58
65
|
|
|
59
66
|
/**
|
|
60
67
|
* Calculate PageRank for all nodes in the graph
|
|
68
|
+
*
|
|
69
|
+
* Uses delta-based optimization by default for improved performance on larger graphs.
|
|
70
|
+
* Automatically falls back to standard algorithm for very small graphs.
|
|
71
|
+
*
|
|
72
|
+
* The delta-based approach provides significant speedup for:
|
|
73
|
+
* - Incremental updates after graph modifications
|
|
74
|
+
* - Graphs with localized changes
|
|
75
|
+
* - Early convergence detection per vertex
|
|
76
|
+
*
|
|
77
|
+
* For initial computation on small-medium graphs, standard algorithm may be faster
|
|
78
|
+
* due to lower overhead.
|
|
79
|
+
* @param graph - The directed input graph to analyze
|
|
80
|
+
* @param options - Algorithm configuration options
|
|
81
|
+
* @returns PageRank result containing ranks, iteration count, and convergence status
|
|
61
82
|
*/
|
|
62
|
-
export function pageRank(
|
|
63
|
-
graph: Graph,
|
|
64
|
-
options: PageRankOptions = {},
|
|
65
|
-
): PageRankResult {
|
|
83
|
+
export function pageRank(graph: Graph, options: PageRankOptions = {}): PageRankResult {
|
|
66
84
|
const {
|
|
67
85
|
dampingFactor = 0.85,
|
|
68
86
|
maxIterations = 100,
|
|
@@ -84,7 +102,50 @@ export function pageRank(
|
|
|
84
102
|
const n = nodes.length;
|
|
85
103
|
|
|
86
104
|
if (n === 0) {
|
|
87
|
-
return {ranks: {}, iterations: 0, converged: true};
|
|
105
|
+
return { ranks: {}, iterations: 0, converged: true };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Use delta-based optimization by default for larger graphs
|
|
109
|
+
// Only disable if explicitly requested or graph is very small (overhead dominates)
|
|
110
|
+
const shouldUseDelta = options.useDelta !== false && n > 100;
|
|
111
|
+
|
|
112
|
+
if (shouldUseDelta) {
|
|
113
|
+
// Use optimized delta-based implementation
|
|
114
|
+
|
|
115
|
+
const deltaOptions: {
|
|
116
|
+
dampingFactor: number;
|
|
117
|
+
tolerance: number;
|
|
118
|
+
maxIterations: number;
|
|
119
|
+
personalization?: Map<NodeId, number>;
|
|
120
|
+
weight?: string;
|
|
121
|
+
} = {
|
|
122
|
+
dampingFactor,
|
|
123
|
+
tolerance,
|
|
124
|
+
maxIterations,
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
if (personalization) {
|
|
128
|
+
deltaOptions.personalization = personalization;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (weight) {
|
|
132
|
+
deltaOptions.weight = weight;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const deltaPageRank = new SimpleDeltaPageRank(graph);
|
|
136
|
+
const deltaRanks = deltaPageRank.compute(deltaOptions);
|
|
137
|
+
|
|
138
|
+
// Convert to string-keyed record
|
|
139
|
+
const result: Record<string, number> = {};
|
|
140
|
+
for (const [nodeId, rank] of deltaRanks) {
|
|
141
|
+
result[String(nodeId)] = rank;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
ranks: result,
|
|
146
|
+
iterations: maxIterations, // For now, assume we used all iterations
|
|
147
|
+
converged: true,
|
|
148
|
+
};
|
|
88
149
|
}
|
|
89
150
|
|
|
90
151
|
// Initialize PageRank values
|
|
@@ -160,7 +221,7 @@ export function pageRank(
|
|
|
160
221
|
}
|
|
161
222
|
|
|
162
223
|
if (danglingSum > 0) {
|
|
163
|
-
const danglingContribution = dampingFactor * danglingSum / n;
|
|
224
|
+
const danglingContribution = (dampingFactor * danglingSum) / n;
|
|
164
225
|
for (const nodeId of nodes) {
|
|
165
226
|
const currentRank = newRanks.get(nodeId) ?? 0;
|
|
166
227
|
if (personalVector) {
|
|
@@ -223,12 +284,21 @@ export function pageRank(
|
|
|
223
284
|
|
|
224
285
|
/**
|
|
225
286
|
* Calculate Personalized PageRank for a specific set of source nodes
|
|
287
|
+
* @param graph - The directed input graph to analyze
|
|
288
|
+
* @param personalNodes - Nodes to personalize the PageRank towards
|
|
289
|
+
* @param options - Algorithm configuration options
|
|
290
|
+
* @returns PageRank result containing ranks, iteration count, and convergence status
|
|
226
291
|
*/
|
|
227
292
|
export function personalizedPageRank(
|
|
228
293
|
graph: Graph,
|
|
229
294
|
personalNodes: NodeId[],
|
|
230
295
|
options: Omit<PageRankOptions, "personalization"> = {},
|
|
231
296
|
): PageRankResult {
|
|
297
|
+
// Handle empty personal nodes by falling back to standard PageRank
|
|
298
|
+
if (personalNodes.length === 0) {
|
|
299
|
+
return pageRank(graph, options);
|
|
300
|
+
}
|
|
301
|
+
|
|
232
302
|
const nodes = Array.from(graph.nodes()).map((node) => node.id);
|
|
233
303
|
const personalization = new Map<NodeId, number>();
|
|
234
304
|
|
|
@@ -248,35 +318,39 @@ export function personalizedPageRank(
|
|
|
248
318
|
}
|
|
249
319
|
|
|
250
320
|
return pageRank(graph, {
|
|
251
|
-
...
|
|
321
|
+
...options,
|
|
252
322
|
personalization,
|
|
253
323
|
});
|
|
254
324
|
}
|
|
255
325
|
|
|
256
326
|
/**
|
|
257
327
|
* Calculate PageRank centrality (normalized PageRank scores)
|
|
328
|
+
* @param graph - The directed input graph to analyze
|
|
329
|
+
* @param options - Algorithm configuration options
|
|
330
|
+
* @returns PageRank scores for each node keyed by node ID
|
|
258
331
|
*/
|
|
259
|
-
export function pageRankCentrality(
|
|
260
|
-
graph: Graph,
|
|
261
|
-
options: PageRankOptions = {},
|
|
262
|
-
): Record<string, number> {
|
|
332
|
+
export function pageRankCentrality(graph: Graph, options: PageRankOptions = {}): Record<string, number> {
|
|
263
333
|
const result = pageRank(graph, options);
|
|
264
334
|
return result.ranks;
|
|
265
335
|
}
|
|
266
336
|
|
|
267
337
|
/**
|
|
268
338
|
* Get the top-k nodes by PageRank score
|
|
339
|
+
* @param graph - The directed input graph to analyze
|
|
340
|
+
* @param k - Number of top nodes to return
|
|
341
|
+
* @param options - Algorithm configuration options
|
|
342
|
+
* @returns Array of top-k nodes with their PageRank scores, sorted descending
|
|
269
343
|
*/
|
|
270
344
|
export function topPageRankNodes(
|
|
271
345
|
graph: Graph,
|
|
272
346
|
k: number,
|
|
273
347
|
options: PageRankOptions = {},
|
|
274
|
-
): {node: NodeId
|
|
348
|
+
): { node: NodeId; rank: number }[] {
|
|
275
349
|
const result = pageRank(graph, options);
|
|
276
350
|
|
|
277
|
-
const nodeRanks: {node: NodeId
|
|
351
|
+
const nodeRanks: { node: NodeId; rank: number }[] = [];
|
|
278
352
|
for (const [nodeStr, rank] of Object.entries(result.ranks)) {
|
|
279
|
-
nodeRanks.push({node: nodeStr as NodeId, rank});
|
|
353
|
+
nodeRanks.push({ node: nodeStr as NodeId, rank });
|
|
280
354
|
}
|
|
281
355
|
|
|
282
356
|
// Sort by rank in descending order
|
|
@@ -287,6 +361,7 @@ export function topPageRankNodes(
|
|
|
287
361
|
|
|
288
362
|
/**
|
|
289
363
|
* Normalize ranks so they sum to 1
|
|
364
|
+
* @param ranks - The ranks map to normalize in place
|
|
290
365
|
*/
|
|
291
366
|
function normalizeRanks(ranks: Map<NodeId, number>): void {
|
|
292
367
|
let sum = 0;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {Graph} from "../../core/graph.js";
|
|
2
|
-
import type {CommunityResult, ComponentResult, GirvanNewmanOptions, NodeId} from "../../types/index.js";
|
|
3
|
-
import {connectedComponents} from "../components/connected.js";
|
|
1
|
+
import { Graph } from "../../core/graph.js";
|
|
2
|
+
import type { CommunityResult, ComponentResult, GirvanNewmanOptions, NodeId } from "../../types/index.js";
|
|
3
|
+
import { connectedComponents } from "../components/connected.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Girvan-Newman community detection algorithm
|
|
@@ -14,22 +14,20 @@ import {connectedComponents} from "../components/connected.js";
|
|
|
14
14
|
*
|
|
15
15
|
* References:
|
|
16
16
|
* - Girvan, M., & Newman, M. E. J. (2002). Community structure in social
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* and biological networks. Proceedings of the National Academy of Sciences,
|
|
18
|
+
* 99(12), 7821-7826.
|
|
20
19
|
* @param graph - The input graph
|
|
21
20
|
* @param options - Algorithm options
|
|
22
21
|
* @returns Array of community detection results representing the dendrogram
|
|
23
22
|
*/
|
|
24
|
-
export function girvanNewman(
|
|
25
|
-
|
|
26
|
-
options: GirvanNewmanOptions = {},
|
|
27
|
-
): CommunityResult[] {
|
|
28
|
-
const {maxCommunities} = options;
|
|
23
|
+
export function girvanNewman(graph: Graph, options: GirvanNewmanOptions = {}): CommunityResult[] {
|
|
24
|
+
const { maxCommunities } = options;
|
|
29
25
|
const minCommunitySize = options.minCommunitySize ?? 1;
|
|
26
|
+
const maxIterations = options.maxIterations ?? 100; // Prevent infinite loops
|
|
30
27
|
|
|
31
28
|
const dendrogram: CommunityResult[] = [];
|
|
32
|
-
const workingGraph =
|
|
29
|
+
const workingGraph = graph.clone();
|
|
30
|
+
let iterations = 0;
|
|
33
31
|
|
|
34
32
|
// Initial state: one large component
|
|
35
33
|
let components = getConnectedComponentsResult(workingGraph);
|
|
@@ -38,7 +36,8 @@ export function girvanNewman(
|
|
|
38
36
|
modularity: calculateModularity(graph, components.componentMap),
|
|
39
37
|
});
|
|
40
38
|
|
|
41
|
-
while (Array.from(workingGraph.edges()).length > 0) {
|
|
39
|
+
while (Array.from(workingGraph.edges()).length > 0 && iterations < maxIterations) {
|
|
40
|
+
iterations++;
|
|
42
41
|
// Calculate edge betweenness centrality
|
|
43
42
|
const edgeBetweenness = calculateEdgeBetweenness(workingGraph);
|
|
44
43
|
|
|
@@ -47,20 +46,20 @@ export function girvanNewman(
|
|
|
47
46
|
}
|
|
48
47
|
|
|
49
48
|
// Find edges with maximum betweenness
|
|
50
|
-
const maxBetweenness = Math.max(...
|
|
51
|
-
const edgesToRemove: {source: NodeId
|
|
49
|
+
const maxBetweenness = Math.max(...edgeBetweenness.values());
|
|
50
|
+
const edgesToRemove: { source: NodeId; target: NodeId }[] = [];
|
|
52
51
|
|
|
53
52
|
for (const [edgeKey, centrality] of edgeBetweenness) {
|
|
54
53
|
if (Math.abs(centrality - maxBetweenness) < 1e-10) {
|
|
55
54
|
const [source, target] = edgeKey.split("|");
|
|
56
55
|
if (source && target) {
|
|
57
|
-
edgesToRemove.push({source, target});
|
|
56
|
+
edgesToRemove.push({ source, target });
|
|
58
57
|
}
|
|
59
58
|
}
|
|
60
59
|
}
|
|
61
60
|
|
|
62
61
|
// Remove edges with highest betweenness
|
|
63
|
-
for (const {source, target} of edgesToRemove) {
|
|
62
|
+
for (const { source, target } of edgesToRemove) {
|
|
64
63
|
workingGraph.removeEdge(source, target);
|
|
65
64
|
}
|
|
66
65
|
|
|
@@ -68,9 +67,7 @@ export function girvanNewman(
|
|
|
68
67
|
components = getConnectedComponentsResult(workingGraph);
|
|
69
68
|
|
|
70
69
|
// Filter communities by minimum size
|
|
71
|
-
const validCommunities = components.components.filter(
|
|
72
|
-
(community) => community.length >= minCommunitySize,
|
|
73
|
-
);
|
|
70
|
+
const validCommunities = components.components.filter((community) => community.length >= minCommunitySize);
|
|
74
71
|
|
|
75
72
|
// Calculate modularity for the new community structure
|
|
76
73
|
const modularity = calculateModularity(graph, components.componentMap);
|
|
@@ -99,6 +96,8 @@ export function girvanNewman(
|
|
|
99
96
|
*
|
|
100
97
|
* Edge betweenness is the fraction of shortest paths that pass through the edge.
|
|
101
98
|
* We adapt node betweenness centrality calculation to work with edges.
|
|
99
|
+
* @param graph - The input graph to analyze
|
|
100
|
+
* @returns Map of edge keys to their betweenness centrality values
|
|
102
101
|
*/
|
|
103
102
|
function calculateEdgeBetweenness(graph: Graph): Map<string, number> {
|
|
104
103
|
const edgeBetweenness = new Map<string, number>();
|
|
@@ -114,7 +113,7 @@ function calculateEdgeBetweenness(graph: Graph): Map<string, number> {
|
|
|
114
113
|
const source = sourceNode.id;
|
|
115
114
|
|
|
116
115
|
// Run BFS to find all shortest paths from source
|
|
117
|
-
const {distances, predecessors, pathCounts} = findAllShortestPaths(graph, source);
|
|
116
|
+
const { distances, predecessors, pathCounts } = findAllShortestPaths(graph, source);
|
|
118
117
|
|
|
119
118
|
// Calculate dependency for each node and accumulate edge betweenness
|
|
120
119
|
const dependency = new Map<NodeId, number>();
|
|
@@ -187,9 +186,15 @@ function calculateEdgeBetweenness(graph: Graph): Map<string, number> {
|
|
|
187
186
|
}
|
|
188
187
|
|
|
189
188
|
/**
|
|
190
|
-
* Find all shortest paths from a source node using BFS
|
|
189
|
+
* Find all shortest paths from a source node using optimized BFS
|
|
190
|
+
* @param graph - The input graph to search
|
|
191
|
+
* @param source - The source node to compute shortest paths from
|
|
192
|
+
* @returns Object containing distances, predecessors, and path counts
|
|
191
193
|
*/
|
|
192
|
-
function findAllShortestPaths(
|
|
194
|
+
function findAllShortestPaths(
|
|
195
|
+
graph: Graph,
|
|
196
|
+
source: NodeId,
|
|
197
|
+
): {
|
|
193
198
|
distances: Map<NodeId, number>;
|
|
194
199
|
predecessors: Map<NodeId, NodeId[]>;
|
|
195
200
|
pathCounts: Map<NodeId, number>;
|
|
@@ -198,39 +203,43 @@ function findAllShortestPaths(graph: Graph, source: NodeId): {
|
|
|
198
203
|
const predecessors = new Map<NodeId, NodeId[]>();
|
|
199
204
|
const pathCounts = new Map<NodeId, number>();
|
|
200
205
|
const queue: NodeId[] = [];
|
|
206
|
+
const visited = new Set<NodeId>();
|
|
201
207
|
|
|
202
|
-
//
|
|
203
|
-
for (const node of graph.nodes()) {
|
|
204
|
-
distances.set(node.id, Infinity);
|
|
205
|
-
predecessors.set(node.id, []);
|
|
206
|
-
pathCounts.set(node.id, 0);
|
|
207
|
-
}
|
|
208
|
-
|
|
208
|
+
// Only initialize for reachable nodes
|
|
209
209
|
distances.set(source, 0);
|
|
210
|
+
predecessors.set(source, []);
|
|
210
211
|
pathCounts.set(source, 1);
|
|
211
212
|
queue.push(source);
|
|
212
213
|
|
|
213
|
-
// BFS
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
214
|
+
// Optimized BFS with early termination
|
|
215
|
+
let queueIndex = 0;
|
|
216
|
+
while (queueIndex < queue.length) {
|
|
217
|
+
const current = queue[queueIndex++];
|
|
218
|
+
if (!current) {
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (visited.has(current)) {
|
|
223
|
+
continue;
|
|
218
224
|
}
|
|
219
225
|
|
|
226
|
+
visited.add(current);
|
|
227
|
+
|
|
220
228
|
const currentDistance = distances.get(current);
|
|
221
229
|
if (currentDistance === undefined) {
|
|
222
230
|
continue;
|
|
223
231
|
}
|
|
224
232
|
|
|
225
233
|
for (const neighbor of graph.neighbors(current)) {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
const newDistance = currentDistance + edgeWeight;
|
|
229
|
-
const neighborDistance = distances.get(neighbor);
|
|
230
|
-
if (neighborDistance === undefined) {
|
|
234
|
+
// Skip if already processed
|
|
235
|
+
if (visited.has(neighbor)) {
|
|
231
236
|
continue;
|
|
232
237
|
}
|
|
233
238
|
|
|
239
|
+
const edgeWeight = 1; // Unweighted for community detection
|
|
240
|
+
const newDistance = currentDistance + edgeWeight;
|
|
241
|
+
const neighborDistance = distances.get(neighbor) ?? Infinity;
|
|
242
|
+
|
|
234
243
|
if (newDistance < neighborDistance) {
|
|
235
244
|
// Found shorter path
|
|
236
245
|
distances.set(neighbor, newDistance);
|
|
@@ -241,25 +250,28 @@ function findAllShortestPaths(graph: Graph, source: NodeId): {
|
|
|
241
250
|
}
|
|
242
251
|
|
|
243
252
|
queue.push(neighbor);
|
|
244
|
-
} else if (
|
|
253
|
+
} else if (newDistance === neighborDistance) {
|
|
245
254
|
// Found alternative shortest path
|
|
246
255
|
const neighborPredecessors = predecessors.get(neighbor);
|
|
247
|
-
|
|
248
|
-
const currentPathCount = pathCounts.get(current);
|
|
249
|
-
|
|
250
|
-
if (neighborPredecessors && neighborPathCount !== undefined && currentPathCount !== undefined) {
|
|
256
|
+
if (neighborPredecessors) {
|
|
251
257
|
neighborPredecessors.push(current);
|
|
252
|
-
pathCounts.
|
|
258
|
+
const currentPathCount = pathCounts.get(current);
|
|
259
|
+
if (currentPathCount !== undefined) {
|
|
260
|
+
pathCounts.set(neighbor, (pathCounts.get(neighbor) ?? 0) + currentPathCount);
|
|
261
|
+
}
|
|
253
262
|
}
|
|
254
263
|
}
|
|
255
264
|
}
|
|
256
265
|
}
|
|
257
266
|
|
|
258
|
-
return {distances, predecessors, pathCounts};
|
|
267
|
+
return { distances, predecessors, pathCounts };
|
|
259
268
|
}
|
|
260
269
|
|
|
261
270
|
/**
|
|
262
271
|
* Generate a consistent edge key for undirected graphs
|
|
272
|
+
* @param source - The source node ID
|
|
273
|
+
* @param target - The target node ID
|
|
274
|
+
* @returns A consistent string key for the edge (ordered alphabetically)
|
|
263
275
|
*/
|
|
264
276
|
function getEdgeKey(source: NodeId, target: NodeId): string {
|
|
265
277
|
// For undirected graphs, ensure consistent ordering
|
|
@@ -274,31 +286,39 @@ function getEdgeKey(source: NodeId, target: NodeId): string {
|
|
|
274
286
|
}
|
|
275
287
|
|
|
276
288
|
/**
|
|
277
|
-
* Calculate modularity for a given community structure
|
|
289
|
+
* Calculate modularity for a given community structure - optimized version
|
|
290
|
+
* @param graph - The original graph
|
|
291
|
+
* @param communityMap - Map from node IDs to community indices
|
|
292
|
+
* @returns The modularity score of the partition
|
|
278
293
|
*/
|
|
279
|
-
function calculateModularity(
|
|
280
|
-
graph: Graph,
|
|
281
|
-
communityMap: Map<NodeId, number>,
|
|
282
|
-
): number {
|
|
294
|
+
function calculateModularity(graph: Graph, communityMap: Map<NodeId, number>): number {
|
|
283
295
|
const totalEdgeWeight = getTotalEdgeWeight(graph);
|
|
284
296
|
if (totalEdgeWeight === 0) {
|
|
285
297
|
return 0;
|
|
286
298
|
}
|
|
287
299
|
|
|
288
300
|
let modularity = 0;
|
|
301
|
+
const degrees = new Map<NodeId, number>();
|
|
289
302
|
|
|
290
|
-
//
|
|
291
|
-
for (const
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
const edge = graph.getEdge(nodeI.id, nodeJ.id);
|
|
295
|
-
const edgeWeight = edge?.weight ?? 0;
|
|
296
|
-
|
|
297
|
-
const degreeI = getNodeDegree(graph, nodeI.id);
|
|
298
|
-
const degreeJ = getNodeDegree(graph, nodeJ.id);
|
|
303
|
+
// Pre-calculate all degrees
|
|
304
|
+
for (const node of graph.nodes()) {
|
|
305
|
+
degrees.set(node.id, getNodeDegree(graph, node.id));
|
|
306
|
+
}
|
|
299
307
|
|
|
300
|
-
|
|
308
|
+
// Only iterate over existing edges
|
|
309
|
+
for (const edge of graph.edges()) {
|
|
310
|
+
const communityI = communityMap.get(edge.source);
|
|
311
|
+
const communityJ = communityMap.get(edge.target);
|
|
312
|
+
|
|
313
|
+
if (communityI === communityJ) {
|
|
314
|
+
const edgeWeight = edge.weight ?? 1;
|
|
315
|
+
const degreeI = degrees.get(edge.source);
|
|
316
|
+
const degreeJ = degrees.get(edge.target);
|
|
317
|
+
if (degreeI === undefined || degreeJ === undefined) {
|
|
318
|
+
continue;
|
|
301
319
|
}
|
|
320
|
+
|
|
321
|
+
modularity += edgeWeight - (degreeI * degreeJ) / (2 * totalEdgeWeight);
|
|
302
322
|
}
|
|
303
323
|
}
|
|
304
324
|
|
|
@@ -307,6 +327,8 @@ function calculateModularity(
|
|
|
307
327
|
|
|
308
328
|
/**
|
|
309
329
|
* Calculate total edge weight in the graph
|
|
330
|
+
* @param graph - The input graph
|
|
331
|
+
* @returns Total sum of all edge weights
|
|
310
332
|
*/
|
|
311
333
|
function getTotalEdgeWeight(graph: Graph): number {
|
|
312
334
|
let totalWeight = 0;
|
|
@@ -320,6 +342,9 @@ function getTotalEdgeWeight(graph: Graph): number {
|
|
|
320
342
|
|
|
321
343
|
/**
|
|
322
344
|
* Get the total degree (sum of edge weights) for a node
|
|
345
|
+
* @param graph - The input graph
|
|
346
|
+
* @param nodeId - The node ID to compute degree for
|
|
347
|
+
* @returns The weighted degree of the node
|
|
323
348
|
*/
|
|
324
349
|
function getNodeDegree(graph: Graph, nodeId: NodeId): number {
|
|
325
350
|
let degree = 0;
|
|
@@ -334,6 +359,8 @@ function getNodeDegree(graph: Graph, nodeId: NodeId): number {
|
|
|
334
359
|
|
|
335
360
|
/**
|
|
336
361
|
* Convert connected components result to ComponentResult format
|
|
362
|
+
* @param graph - The input graph
|
|
363
|
+
* @returns Object containing components array and node-to-component map
|
|
337
364
|
*/
|
|
338
365
|
function getConnectedComponentsResult(graph: Graph): ComponentResult {
|
|
339
366
|
const components = connectedComponents(graph);
|
|
@@ -345,28 +372,5 @@ function getConnectedComponentsResult(graph: Graph): ComponentResult {
|
|
|
345
372
|
});
|
|
346
373
|
});
|
|
347
374
|
|
|
348
|
-
return {components, componentMap};
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
/**
|
|
352
|
-
* Create a deep clone of the graph
|
|
353
|
-
*/
|
|
354
|
-
function cloneGraph(graph: Graph): Graph {
|
|
355
|
-
const clone = new Graph({
|
|
356
|
-
directed: graph.isDirected,
|
|
357
|
-
allowSelfLoops: true,
|
|
358
|
-
allowParallelEdges: false,
|
|
359
|
-
});
|
|
360
|
-
|
|
361
|
-
// Add all nodes
|
|
362
|
-
for (const node of graph.nodes()) {
|
|
363
|
-
clone.addNode(node.id, node.data);
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
// Add all edges
|
|
367
|
-
for (const edge of graph.edges()) {
|
|
368
|
-
clone.addEdge(edge.source, edge.target, edge.weight, edge.data);
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
return clone;
|
|
375
|
+
return { components, componentMap };
|
|
372
376
|
}
|
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
* than with the rest of the network.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
export {girvanNewman} from "./girvan-newman.js";
|
|
10
|
-
export {
|
|
11
|
-
export {
|
|
12
|
-
export {
|
|
13
|
-
|
|
9
|
+
export { girvanNewman } from "./girvan-newman.js";
|
|
10
|
+
export type { LabelPropagationOptions, LabelPropagationResult } from "./label-propagation.js";
|
|
11
|
+
export { labelPropagation, labelPropagationAsync, labelPropagationSemiSupervised } from "./label-propagation.js";
|
|
12
|
+
export type { LeidenOptions, LeidenResult } from "./leiden.js";
|
|
13
|
+
export { leiden } from "./leiden.js";
|
|
14
|
+
export { louvain } from "./louvain.js";
|