@graphty/algorithms 1.3.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +368 -422
- package/dist/algorithms.js +567 -264
- package/dist/algorithms.js.map +1 -1
- package/dist/src/algorithms/centrality/betweenness.d.ts +10 -0
- package/dist/src/algorithms/centrality/betweenness.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/betweenness.js +27 -6
- package/dist/src/algorithms/centrality/betweenness.js.map +1 -1
- package/dist/src/algorithms/centrality/closeness.d.ts +11 -2
- package/dist/src/algorithms/centrality/closeness.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/closeness.js +17 -3
- 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 +9 -6
- package/dist/src/algorithms/centrality/degree.js.map +1 -1
- package/dist/src/algorithms/centrality/delta-pagerank-simple.d.ts +21 -3
- package/dist/src/algorithms/centrality/delta-pagerank-simple.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/delta-pagerank-simple.js +25 -7
- package/dist/src/algorithms/centrality/delta-pagerank-simple.js.map +1 -1
- package/dist/src/algorithms/centrality/delta-pagerank.d.ts +28 -2
- package/dist/src/algorithms/centrality/delta-pagerank.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/delta-pagerank.js +30 -4
- package/dist/src/algorithms/centrality/delta-pagerank.js.map +1 -1
- 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 +1 -1
- package/dist/src/algorithms/centrality/index.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/index.js +1 -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 +14 -0
- package/dist/src/algorithms/centrality/pagerank.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/pagerank.js +16 -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 +21 -4
- package/dist/src/algorithms/community/girvan-newman.js.map +1 -1
- 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 +0 -3
- package/dist/src/algorithms/community/label-propagation.d.ts.map +1 -1
- package/dist/src/algorithms/community/label-propagation.js +13 -6
- package/dist/src/algorithms/community/label-propagation.js.map +1 -1
- package/dist/src/algorithms/community/leiden.d.ts +0 -1
- package/dist/src/algorithms/community/leiden.d.ts.map +1 -1
- package/dist/src/algorithms/community/leiden.js +37 -6
- package/dist/src/algorithms/community/leiden.js.map +1 -1
- package/dist/src/algorithms/community/louvain-optimized.d.ts +37 -0
- package/dist/src/algorithms/community/louvain-optimized.d.ts.map +1 -1
- package/dist/src/algorithms/community/louvain-optimized.js +42 -7
- package/dist/src/algorithms/community/louvain-optimized.js.map +1 -1
- 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 +19 -6
- package/dist/src/algorithms/community/louvain.js.map +1 -1
- package/dist/src/algorithms/community/modularity-utils.d.ts +0 -4
- package/dist/src/algorithms/community/modularity-utils.d.ts.map +1 -1
- package/dist/src/algorithms/community/modularity-utils.js +1 -5
- package/dist/src/algorithms/community/modularity-utils.js.map +1 -1
- 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 +10 -0
- 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 +10 -0
- package/dist/src/algorithms/shortest-path/bellman-ford.js.map +1 -1
- package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.d.ts +12 -5
- package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.d.ts.map +1 -1
- package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.js +19 -17
- package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.js.map +1 -1
- package/dist/src/algorithms/shortest-path/dijkstra.d.ts +15 -0
- package/dist/src/algorithms/shortest-path/dijkstra.d.ts.map +1 -1
- package/dist/src/algorithms/shortest-path/dijkstra.js +15 -0
- 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 +13 -0
- package/dist/src/algorithms/traversal/bfs-unified.d.ts.map +1 -1
- package/dist/src/algorithms/traversal/bfs-unified.js +37 -0
- package/dist/src/algorithms/traversal/bfs-unified.js.map +1 -1
- package/dist/src/algorithms/traversal/bfs-variants.d.ts +23 -0
- package/dist/src/algorithms/traversal/bfs-variants.d.ts.map +1 -1
- package/dist/src/algorithms/traversal/bfs-variants.js +34 -0
- package/dist/src/algorithms/traversal/bfs-variants.js.map +1 -1
- package/dist/src/algorithms/traversal/bfs.d.ts +1 -1
- package/dist/src/algorithms/traversal/bfs.d.ts.map +1 -1
- package/dist/src/algorithms/traversal/bfs.js +1 -1
- 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 +2 -0
- package/dist/src/benchmark-all-algorithms.d.ts.map +1 -1
- package/dist/src/benchmark-all-algorithms.js +32 -3
- package/dist/src/benchmark-all-algorithms.js.map +1 -1
- package/dist/src/clustering/hierarchical.d.ts +8 -1
- package/dist/src/clustering/hierarchical.d.ts.map +1 -1
- package/dist/src/clustering/hierarchical.js +22 -6
- package/dist/src/clustering/hierarchical.js.map +1 -1
- package/dist/src/clustering/index.d.ts.map +1 -1
- package/dist/src/clustering/index.js.map +1 -1
- package/dist/src/clustering/k-core.d.ts +2 -5
- package/dist/src/clustering/k-core.d.ts.map +1 -1
- package/dist/src/clustering/k-core.js +14 -12
- 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 +4 -1
- package/dist/src/clustering/spectral.d.ts.map +1 -1
- package/dist/src/clustering/spectral.js +61 -28
- 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 +45 -1
- 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 +4 -2
- package/dist/src/flow/ford-fulkerson.d.ts.map +1 -1
- package/dist/src/flow/ford-fulkerson.js +31 -2
- package/dist/src/flow/ford-fulkerson.js.map +1 -1
- package/dist/src/flow/min-cut.d.ts +0 -3
- package/dist/src/flow/min-cut.d.ts.map +1 -1
- package/dist/src/flow/min-cut.js +17 -4
- package/dist/src/flow/min-cut.js.map +1 -1
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/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 +36 -10
- 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 +27 -6
- 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 +103 -53
- package/dist/src/optimized/bit-packed.d.ts.map +1 -1
- package/dist/src/optimized/bit-packed.js +104 -54
- package/dist/src/optimized/bit-packed.js.map +1 -1
- package/dist/src/optimized/csr-graph.d.ts +87 -24
- package/dist/src/optimized/csr-graph.d.ts.map +1 -1
- package/dist/src/optimized/csr-graph.js +87 -24
- package/dist/src/optimized/csr-graph.js.map +1 -1
- package/dist/src/optimized/direction-optimized-bfs.d.ts +37 -16
- package/dist/src/optimized/direction-optimized-bfs.d.ts.map +1 -1
- package/dist/src/optimized/direction-optimized-bfs.js +39 -20
- package/dist/src/optimized/direction-optimized-bfs.js.map +1 -1
- package/dist/src/optimized/graph-adapter.d.ts +58 -9
- package/dist/src/optimized/graph-adapter.d.ts.map +1 -1
- package/dist/src/optimized/graph-adapter.js +58 -10
- package/dist/src/optimized/graph-adapter.js.map +1 -1
- package/dist/src/optimized/index.d.ts +1 -1
- package/dist/src/optimized/index.d.ts.map +1 -1
- package/dist/src/optimized/index.js +3 -1
- package/dist/src/optimized/index.js.map +1 -1
- 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 +23 -10
- 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 +29 -8
- package/dist/src/research/sync.js.map +1 -1
- package/dist/src/research/terahac.d.ts +0 -1
- package/dist/src/research/terahac.d.ts.map +1 -1
- package/dist/src/research/terahac.js +32 -4
- package/dist/src/research/terahac.js.map +1 -1
- package/dist/src/utils/graph-converters.d.ts +31 -0
- package/dist/src/utils/graph-converters.d.ts.map +1 -1
- package/dist/src/utils/graph-converters.js +31 -0
- package/dist/src/utils/graph-converters.js.map +1 -1
- package/dist/src/utils/graph-utilities.d.ts.map +1 -1
- package/dist/src/utils/graph-utilities.js.map +1 -1
- package/dist/src/utils/math-utilities.d.ts +11 -0
- package/dist/src/utils/math-utilities.d.ts.map +1 -1
- package/dist/src/utils/math-utilities.js +14 -5
- package/dist/src/utils/math-utilities.js.map +1 -1
- package/dist/src/utils/optimization-helpers.d.ts +9 -0
- package/dist/src/utils/optimization-helpers.d.ts.map +1 -1
- package/dist/src/utils/optimization-helpers.js +12 -0
- package/dist/src/utils/optimization-helpers.js.map +1 -1
- 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/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +56 -65
- package/src/algorithms/centrality/betweenness.ts +34 -17
- package/src/algorithms/centrality/closeness.ts +34 -17
- package/src/algorithms/centrality/degree.ts +15 -19
- package/src/algorithms/centrality/delta-pagerank-simple.ts +36 -28
- package/src/algorithms/centrality/delta-pagerank.ts +34 -11
- package/src/algorithms/centrality/eigenvector.ts +14 -15
- package/src/algorithms/centrality/hits.ts +17 -17
- package/src/algorithms/centrality/index.ts +20 -15
- package/src/algorithms/centrality/katz.ts +17 -25
- package/src/algorithms/centrality/pagerank.ts +26 -17
- package/src/algorithms/community/girvan-newman.ts +39 -28
- package/src/algorithms/community/index.ts +6 -7
- package/src/algorithms/community/label-propagation.ts +20 -28
- package/src/algorithms/community/leiden.ts +61 -37
- package/src/algorithms/community/louvain-optimized.ts +49 -20
- package/src/algorithms/community/louvain.ts +35 -25
- package/src/algorithms/community/modularity-utils.ts +5 -17
- package/src/algorithms/components/connected.ts +40 -17
- package/src/algorithms/matching/bipartite.ts +17 -10
- 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 -15
- package/src/algorithms/shortest-path/bidirectional-dijkstra.ts +29 -29
- package/src/algorithms/shortest-path/dijkstra.ts +23 -17
- 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 +64 -60
- package/src/algorithms/traversal/bfs-variants.ts +61 -37
- package/src/algorithms/traversal/bfs.ts +1 -7
- package/src/algorithms/traversal/dfs.ts +61 -42
- package/src/algorithms/traversal/index.ts +3 -3
- package/src/benchmark-all-algorithms.ts +57 -25
- package/src/clustering/hierarchical.ts +40 -34
- package/src/clustering/index.ts +8 -8
- package/src/clustering/k-core.ts +26 -42
- package/src/clustering/mcl.ts +53 -23
- package/src/clustering/spectral.ts +91 -57
- package/src/core/graph.ts +54 -14
- 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 +62 -35
- package/src/flow/min-cut.ts +43 -45
- package/src/index.ts +3 -2
- package/src/link-prediction/adamic-adar.ts +65 -51
- package/src/link-prediction/common-neighbors.ts +45 -36
- package/src/link-prediction/index.ts +1 -1
- package/src/optimized/bit-packed.ts +106 -56
- package/src/optimized/csr-graph.ts +93 -30
- package/src/optimized/direction-optimized-bfs.ts +44 -25
- package/src/optimized/graph-adapter.ts +64 -16
- package/src/optimized/index.ts +7 -9
- package/src/pathfinding/astar.ts +40 -25
- package/src/pathfinding/utils.ts +20 -13
- package/src/research/grsbm.ts +31 -25
- package/src/research/index.ts +4 -4
- package/src/research/sync.ts +40 -24
- package/src/research/terahac.ts +54 -20
- package/src/utils/graph-converters.ts +42 -14
- package/src/utils/graph-utilities.ts +11 -37
- package/src/utils/math-utilities.ts +17 -8
- package/src/utils/optimization-helpers.ts +27 -21
- package/src/utils/priorityQueue.ts +40 -6
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {Graph} from "../../core/graph.js";
|
|
2
|
-
import type {CentralityOptions, CentralityResult} from "../../types/index.js";
|
|
1
|
+
import type { Graph } from "../../core/graph.js";
|
|
2
|
+
import type { CentralityOptions, CentralityResult } from "../../types/index.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Degree centrality implementation
|
|
@@ -10,13 +10,13 @@ import type {CentralityOptions, CentralityResult} from "../../types/index.js";
|
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Calculate degree centrality for all nodes in the graph
|
|
13
|
+
* @param graph - The input graph to analyze
|
|
14
|
+
* @param options - Algorithm configuration options
|
|
15
|
+
* @returns Centrality scores for each node keyed by node ID
|
|
13
16
|
*/
|
|
14
|
-
export function degreeCentrality(
|
|
15
|
-
graph: Graph,
|
|
16
|
-
options: CentralityOptions = {},
|
|
17
|
-
): CentralityResult {
|
|
17
|
+
export function degreeCentrality(graph: Graph, options: CentralityOptions = {}): CentralityResult {
|
|
18
18
|
const centrality: CentralityResult = {};
|
|
19
|
-
const {nodeCount} = graph;
|
|
19
|
+
const { nodeCount } = graph;
|
|
20
20
|
|
|
21
21
|
// Calculate normalization factor (same for both directed and undirected graphs)
|
|
22
22
|
const maxPossibleDegree = nodeCount - 1;
|
|
@@ -49,9 +49,7 @@ export function degreeCentrality(
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
// Apply normalization if requested
|
|
52
|
-
const normalizedDegree = options.normalized && maxPossibleDegree > 0 ?
|
|
53
|
-
degree / maxPossibleDegree :
|
|
54
|
-
degree;
|
|
52
|
+
const normalizedDegree = options.normalized && maxPossibleDegree > 0 ? degree / maxPossibleDegree : degree;
|
|
55
53
|
|
|
56
54
|
centrality[node.id.toString()] = normalizedDegree;
|
|
57
55
|
}
|
|
@@ -61,17 +59,17 @@ export function degreeCentrality(
|
|
|
61
59
|
|
|
62
60
|
/**
|
|
63
61
|
* Calculate degree centrality for a specific node
|
|
62
|
+
* @param graph - The input graph to analyze
|
|
63
|
+
* @param nodeId - The node to calculate centrality for
|
|
64
|
+
* @param options - Algorithm configuration options
|
|
65
|
+
* @returns The degree centrality score for the node
|
|
64
66
|
*/
|
|
65
|
-
export function nodeDegreeCentrality(
|
|
66
|
-
graph: Graph,
|
|
67
|
-
nodeId: string | number,
|
|
68
|
-
options: CentralityOptions = {},
|
|
69
|
-
): number {
|
|
67
|
+
export function nodeDegreeCentrality(graph: Graph, nodeId: string | number, options: CentralityOptions = {}): number {
|
|
70
68
|
if (!graph.hasNode(nodeId)) {
|
|
71
69
|
throw new Error(`Node ${String(nodeId)} not found in graph`);
|
|
72
70
|
}
|
|
73
71
|
|
|
74
|
-
const {nodeCount} = graph;
|
|
72
|
+
const { nodeCount } = graph;
|
|
75
73
|
let degree: number;
|
|
76
74
|
|
|
77
75
|
if (graph.isDirected && options.mode) {
|
|
@@ -99,7 +97,5 @@ export function nodeDegreeCentrality(
|
|
|
99
97
|
// Apply normalization if requested
|
|
100
98
|
const maxPossibleDegree = nodeCount - 1;
|
|
101
99
|
|
|
102
|
-
return options.normalized && maxPossibleDegree > 0 ?
|
|
103
|
-
degree / maxPossibleDegree :
|
|
104
|
-
degree;
|
|
100
|
+
return options.normalized && maxPossibleDegree > 0 ? degree / maxPossibleDegree : degree;
|
|
105
101
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
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
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Simplified Delta-based PageRank that matches the standard algorithm
|
|
@@ -13,6 +13,10 @@ export class SimpleDeltaPageRank {
|
|
|
13
13
|
private nodeCount: number;
|
|
14
14
|
private previousScores: Map<NodeId, number> | null = null;
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Creates a new SimpleDeltaPageRank instance for the given graph.
|
|
18
|
+
* @param graph - The directed graph to compute PageRank on
|
|
19
|
+
*/
|
|
16
20
|
constructor(graph: Graph) {
|
|
17
21
|
if (!graph.isDirected) {
|
|
18
22
|
throw new Error("PageRank requires a directed graph");
|
|
@@ -22,20 +26,26 @@ export class SimpleDeltaPageRank {
|
|
|
22
26
|
this.nodeCount = graph.nodeCount;
|
|
23
27
|
}
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Computes PageRank scores for all nodes in the graph using power iteration.
|
|
31
|
+
* @param options - Configuration options for PageRank computation
|
|
32
|
+
* @param options.dampingFactor - Probability of following a link (default: 0.85)
|
|
33
|
+
* @param options.tolerance - Convergence tolerance threshold (default: 1e-6)
|
|
34
|
+
* @param options.maxIterations - Maximum number of iterations (default: 100)
|
|
35
|
+
* @param options.personalization - Personalization vector for Personalized PageRank
|
|
36
|
+
* @param options.weight - Edge attribute name for weighted PageRank
|
|
37
|
+
* @returns Map of node IDs to their PageRank scores
|
|
38
|
+
*/
|
|
39
|
+
public compute(
|
|
40
|
+
options: {
|
|
41
|
+
dampingFactor?: number;
|
|
42
|
+
tolerance?: number;
|
|
43
|
+
maxIterations?: number;
|
|
44
|
+
personalization?: Map<NodeId, number>;
|
|
45
|
+
weight?: string;
|
|
46
|
+
} = {},
|
|
47
|
+
): Map<NodeId, number> {
|
|
48
|
+
const { dampingFactor = 0.85, tolerance = 1e-6, maxIterations = 100, personalization, weight } = options;
|
|
39
49
|
|
|
40
50
|
if (this.nodeCount === 0) {
|
|
41
51
|
return new Map();
|
|
@@ -97,7 +107,7 @@ export class SimpleDeltaPageRank {
|
|
|
97
107
|
}
|
|
98
108
|
|
|
99
109
|
if (danglingSum > 0) {
|
|
100
|
-
const danglingContribution = dampingFactor * danglingSum / this.nodeCount;
|
|
110
|
+
const danglingContribution = (dampingFactor * danglingSum) / this.nodeCount;
|
|
101
111
|
for (const nodeId of scores.keys()) {
|
|
102
112
|
const current = newScores.get(nodeId) ?? 0;
|
|
103
113
|
if (personalVector) {
|
|
@@ -175,9 +185,13 @@ export class SimpleDeltaPageRank {
|
|
|
175
185
|
/**
|
|
176
186
|
* Perform incremental update after graph modification.
|
|
177
187
|
* This is where delta-based approach provides significant speedup.
|
|
178
|
-
*
|
|
179
|
-
* @param
|
|
180
|
-
* @param options
|
|
188
|
+
* @param modifiedNodes - Set of nodes that were modified (edges added/removed)
|
|
189
|
+
* @param options - Computation options
|
|
190
|
+
* @param options.dampingFactor - Probability of following a link (default: 0.85)
|
|
191
|
+
* @param options.tolerance - Convergence tolerance threshold (default: 1e-6)
|
|
192
|
+
* @param options.maxIterations - Maximum number of iterations (default: 100)
|
|
193
|
+
* @param options.personalization - Personalization vector for Personalized PageRank
|
|
194
|
+
* @param options.weight - Edge attribute name for weighted PageRank
|
|
181
195
|
* @returns Updated PageRank scores
|
|
182
196
|
*/
|
|
183
197
|
public update(
|
|
@@ -195,13 +209,7 @@ export class SimpleDeltaPageRank {
|
|
|
195
209
|
return this.compute(options);
|
|
196
210
|
}
|
|
197
211
|
|
|
198
|
-
const {
|
|
199
|
-
dampingFactor = 0.85,
|
|
200
|
-
tolerance = 1e-6,
|
|
201
|
-
maxIterations = 100,
|
|
202
|
-
personalization,
|
|
203
|
-
weight,
|
|
204
|
-
} = options;
|
|
212
|
+
const { dampingFactor = 0.85, tolerance = 1e-6, maxIterations = 100, personalization, weight } = options;
|
|
205
213
|
|
|
206
214
|
// Initialize scores from previous computation
|
|
207
215
|
const scores = new Map(this.previousScores);
|
|
@@ -275,7 +283,7 @@ export class SimpleDeltaPageRank {
|
|
|
275
283
|
}
|
|
276
284
|
|
|
277
285
|
if (danglingSum > 0) {
|
|
278
|
-
const danglingContribution = dampingFactor * danglingSum / this.nodeCount;
|
|
286
|
+
const danglingContribution = (dampingFactor * danglingSum) / this.nodeCount;
|
|
279
287
|
for (const nodeId of scores.keys()) {
|
|
280
288
|
const current = newScores.get(nodeId) ?? 0;
|
|
281
289
|
if (personalVector) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {Graph} from "../../core/graph.js";
|
|
2
|
-
import {PriorityQueue} from "../../data-structures/priority-queue.js";
|
|
3
|
-
import type {NodeId} from "../../types/index.js";
|
|
1
|
+
import type { Graph } from "../../core/graph.js";
|
|
2
|
+
import { PriorityQueue } from "../../data-structures/priority-queue.js";
|
|
3
|
+
import type { NodeId } from "../../types/index.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Delta-based PageRank implementation for faster convergence
|
|
@@ -45,6 +45,10 @@ export interface DeltaPageRankOptions {
|
|
|
45
45
|
weight?: string;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Delta-based PageRank class that tracks changes between iterations
|
|
50
|
+
* and only processes nodes with significant changes for improved performance.
|
|
51
|
+
*/
|
|
48
52
|
export class DeltaPageRank {
|
|
49
53
|
private graph: Graph;
|
|
50
54
|
private scores: Map<NodeId, number>;
|
|
@@ -55,6 +59,10 @@ export class DeltaPageRank {
|
|
|
55
59
|
private danglingNodes: Set<NodeId>;
|
|
56
60
|
private nodeCount: number;
|
|
57
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Creates a new DeltaPageRank instance for the given graph.
|
|
64
|
+
* @param graph - The directed graph to compute PageRank on
|
|
65
|
+
*/
|
|
58
66
|
constructor(graph: Graph) {
|
|
59
67
|
if (!graph.isDirected) {
|
|
60
68
|
throw new Error("DeltaPageRank requires a directed graph");
|
|
@@ -101,6 +109,11 @@ export class DeltaPageRank {
|
|
|
101
109
|
}
|
|
102
110
|
}
|
|
103
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Computes PageRank scores using delta-based iteration for faster convergence.
|
|
114
|
+
* @param options - Configuration options for PageRank computation
|
|
115
|
+
* @returns Map of node IDs to their PageRank scores
|
|
116
|
+
*/
|
|
104
117
|
public compute(options: DeltaPageRankOptions = {}): Map<NodeId, number> {
|
|
105
118
|
const {
|
|
106
119
|
dampingFactor = 0.85,
|
|
@@ -149,7 +162,7 @@ export class DeltaPageRank {
|
|
|
149
162
|
}
|
|
150
163
|
|
|
151
164
|
if (danglingSum > 0) {
|
|
152
|
-
const danglingContribution = dampingFactor * danglingSum / this.nodeCount;
|
|
165
|
+
const danglingContribution = (dampingFactor * danglingSum) / this.nodeCount;
|
|
153
166
|
for (const node of this.graph.nodes()) {
|
|
154
167
|
const nodeId = node.id;
|
|
155
168
|
const currentDelta = nextDeltas.get(nodeId) ?? 0;
|
|
@@ -197,7 +210,7 @@ export class DeltaPageRank {
|
|
|
197
210
|
const nodeId = node.id;
|
|
198
211
|
const currentDelta = nextDeltas.get(nodeId) ?? 0;
|
|
199
212
|
if (personalVector) {
|
|
200
|
-
nextDeltas.set(nodeId, currentDelta + (
|
|
213
|
+
nextDeltas.set(nodeId, currentDelta + (1 - dampingFactor) * (personalVector.get(nodeId) ?? 0));
|
|
201
214
|
} else {
|
|
202
215
|
nextDeltas.set(nodeId, currentDelta + randomJump);
|
|
203
216
|
}
|
|
@@ -231,13 +244,13 @@ export class DeltaPageRank {
|
|
|
231
244
|
}
|
|
232
245
|
|
|
233
246
|
/**
|
|
234
|
-
* Update PageRank scores after graph modification
|
|
235
|
-
* This is where delta-based approach really shines
|
|
247
|
+
* Update PageRank scores after graph modification.
|
|
248
|
+
* This is where delta-based approach really shines.
|
|
249
|
+
* @param modifiedNodes - Set of nodes that were modified (edges added/removed)
|
|
250
|
+
* @param options - Configuration options for PageRank computation
|
|
251
|
+
* @returns Updated PageRank scores
|
|
236
252
|
*/
|
|
237
|
-
public update(
|
|
238
|
-
modifiedNodes: Set<NodeId>,
|
|
239
|
-
options: DeltaPageRankOptions = {},
|
|
240
|
-
): Map<NodeId, number> {
|
|
253
|
+
public update(modifiedNodes: Set<NodeId>, options: DeltaPageRankOptions = {}): Map<NodeId, number> {
|
|
241
254
|
// Mark modified nodes and their neighbors as active
|
|
242
255
|
this.activeNodes.clear();
|
|
243
256
|
|
|
@@ -286,6 +299,10 @@ export class PriorityDeltaPageRank {
|
|
|
286
299
|
private danglingNodes: Set<NodeId>;
|
|
287
300
|
private nodeCount: number;
|
|
288
301
|
|
|
302
|
+
/**
|
|
303
|
+
* Creates a new PriorityDeltaPageRank instance for the given graph.
|
|
304
|
+
* @param graph - The directed graph to compute PageRank on
|
|
305
|
+
*/
|
|
289
306
|
constructor(graph: Graph) {
|
|
290
307
|
if (!graph.isDirected) {
|
|
291
308
|
throw new Error("PriorityDeltaPageRank requires a directed graph");
|
|
@@ -332,6 +349,12 @@ export class PriorityDeltaPageRank {
|
|
|
332
349
|
}
|
|
333
350
|
}
|
|
334
351
|
|
|
352
|
+
/**
|
|
353
|
+
* Computes PageRank scores using priority queue-based delta iteration.
|
|
354
|
+
* Processes nodes in order of their delta magnitude for optimal convergence.
|
|
355
|
+
* @param options - Configuration options for PageRank computation
|
|
356
|
+
* @returns Map of node IDs to their PageRank scores
|
|
357
|
+
*/
|
|
335
358
|
public computeWithPriority(options: DeltaPageRankOptions = {}): Map<NodeId, number> {
|
|
336
359
|
const {
|
|
337
360
|
dampingFactor = 0.85,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {Graph} from "../../core/graph.js";
|
|
2
|
-
import type {CentralityOptions, CentralityResult} from "../../types/index.js";
|
|
1
|
+
import type { Graph } from "../../core/graph.js";
|
|
2
|
+
import type { CentralityOptions, CentralityResult } from "../../types/index.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Eigenvector centrality implementation
|
|
@@ -19,19 +19,14 @@ export interface EigenvectorCentralityOptions extends CentralityOptions {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
* Calculate eigenvector centrality for all nodes in the graph
|
|
23
|
-
* Uses the power iteration method to find the dominant eigenvector
|
|
22
|
+
* Calculate eigenvector centrality for all nodes in the graph.
|
|
23
|
+
* Uses the power iteration method to find the dominant eigenvector.
|
|
24
|
+
* @param graph - The graph to compute eigenvector centrality on
|
|
25
|
+
* @param options - Configuration options for the computation
|
|
26
|
+
* @returns Object mapping node IDs to their eigenvector centrality scores
|
|
24
27
|
*/
|
|
25
|
-
export function eigenvectorCentrality(
|
|
26
|
-
|
|
27
|
-
options: EigenvectorCentralityOptions = {},
|
|
28
|
-
): CentralityResult {
|
|
29
|
-
const {
|
|
30
|
-
maxIterations = 100,
|
|
31
|
-
tolerance = 1e-6,
|
|
32
|
-
normalized = true,
|
|
33
|
-
startVector,
|
|
34
|
-
} = options;
|
|
28
|
+
export function eigenvectorCentrality(graph: Graph, options: EigenvectorCentralityOptions = {}): CentralityResult {
|
|
29
|
+
const { maxIterations = 100, tolerance = 1e-6, normalized = true, startVector } = options;
|
|
35
30
|
|
|
36
31
|
const centrality: CentralityResult = {};
|
|
37
32
|
const nodes = Array.from(graph.nodes());
|
|
@@ -146,7 +141,11 @@ export function eigenvectorCentrality(
|
|
|
146
141
|
}
|
|
147
142
|
|
|
148
143
|
/**
|
|
149
|
-
* Calculate eigenvector centrality for a specific node
|
|
144
|
+
* Calculate eigenvector centrality for a specific node.
|
|
145
|
+
* @param graph - The graph to compute eigenvector centrality on
|
|
146
|
+
* @param nodeId - The ID of the node to calculate centrality for
|
|
147
|
+
* @param options - Configuration options for the computation
|
|
148
|
+
* @returns The eigenvector centrality score for the specified node
|
|
150
149
|
*/
|
|
151
150
|
export function nodeEigenvectorCentrality(
|
|
152
151
|
graph: Graph,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {Graph} from "../../core/graph.js";
|
|
2
|
-
import type {CentralityOptions} from "../../types/index.js";
|
|
1
|
+
import type { Graph } from "../../core/graph.js";
|
|
2
|
+
import type { CentralityOptions } from "../../types/index.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* HITS (Hyperlink-Induced Topic Search) algorithm implementation
|
|
@@ -25,18 +25,14 @@ export interface HITSOptions extends CentralityOptions {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
* Calculate HITS hub and authority scores for all nodes in the graph
|
|
29
|
-
* Uses iterative method with normalization
|
|
28
|
+
* Calculate HITS hub and authority scores for all nodes in the graph.
|
|
29
|
+
* Uses iterative method with normalization.
|
|
30
|
+
* @param graph - The graph to compute HITS scores on
|
|
31
|
+
* @param options - Configuration options for the computation
|
|
32
|
+
* @returns Object containing hub and authority scores for all nodes
|
|
30
33
|
*/
|
|
31
|
-
export function hits(
|
|
32
|
-
|
|
33
|
-
options: HITSOptions = {},
|
|
34
|
-
): HITSResult {
|
|
35
|
-
const {
|
|
36
|
-
maxIterations = 100,
|
|
37
|
-
tolerance = 1e-6,
|
|
38
|
-
normalized = true,
|
|
39
|
-
} = options;
|
|
34
|
+
export function hits(graph: Graph, options: HITSOptions = {}): HITSResult {
|
|
35
|
+
const { maxIterations = 100, tolerance = 1e-6, normalized = true } = options;
|
|
40
36
|
|
|
41
37
|
const hubs: Record<string, number> = {};
|
|
42
38
|
const authorities: Record<string, number> = {};
|
|
@@ -45,7 +41,7 @@ export function hits(
|
|
|
45
41
|
const nodeIds = nodes.map((node) => node.id);
|
|
46
42
|
|
|
47
43
|
if (nodeIds.length === 0) {
|
|
48
|
-
return {hubs, authorities};
|
|
44
|
+
return { hubs, authorities };
|
|
49
45
|
}
|
|
50
46
|
|
|
51
47
|
// Initialize scores
|
|
@@ -185,17 +181,21 @@ export function hits(
|
|
|
185
181
|
}
|
|
186
182
|
}
|
|
187
183
|
|
|
188
|
-
return {hubs, authorities};
|
|
184
|
+
return { hubs, authorities };
|
|
189
185
|
}
|
|
190
186
|
|
|
191
187
|
/**
|
|
192
|
-
* Calculate HITS scores for a specific node
|
|
188
|
+
* Calculate HITS scores for a specific node.
|
|
189
|
+
* @param graph - The graph to compute HITS scores on
|
|
190
|
+
* @param nodeId - The ID of the node to calculate scores for
|
|
191
|
+
* @param options - Configuration options for the computation
|
|
192
|
+
* @returns Object containing hub and authority scores for the specified node
|
|
193
193
|
*/
|
|
194
194
|
export function nodeHITS(
|
|
195
195
|
graph: Graph,
|
|
196
196
|
nodeId: string | number,
|
|
197
197
|
options: HITSOptions = {},
|
|
198
|
-
): {hub: number
|
|
198
|
+
): { hub: number; authority: number } {
|
|
199
199
|
if (!graph.hasNode(nodeId)) {
|
|
200
200
|
throw new Error(`Node ${String(nodeId)} not found in graph`);
|
|
201
201
|
}
|
|
@@ -2,18 +2,23 @@
|
|
|
2
2
|
* Centrality algorithms
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
export type {BetweennessCentralityOptions} from "./betweenness.js";
|
|
6
|
-
export {betweennessCentrality, edgeBetweennessCentrality, nodeBetweennessCentrality} from "./betweenness.js";
|
|
7
|
-
export type {ClosenessCentralityOptions} from "./closeness.js";
|
|
8
|
-
export {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
export
|
|
15
|
-
export {
|
|
16
|
-
export
|
|
17
|
-
export {
|
|
18
|
-
export
|
|
19
|
-
export {
|
|
5
|
+
export type { BetweennessCentralityOptions } from "./betweenness.js";
|
|
6
|
+
export { betweennessCentrality, edgeBetweennessCentrality, nodeBetweennessCentrality } from "./betweenness.js";
|
|
7
|
+
export type { ClosenessCentralityOptions } from "./closeness.js";
|
|
8
|
+
export {
|
|
9
|
+
closenessCentrality,
|
|
10
|
+
nodeClosenessCentrality,
|
|
11
|
+
nodeWeightedClosenessCentrality,
|
|
12
|
+
weightedClosenessCentrality,
|
|
13
|
+
} from "./closeness.js";
|
|
14
|
+
export { degreeCentrality, nodeDegreeCentrality } from "./degree.js";
|
|
15
|
+
export type { DeltaPageRankOptions } from "./delta-pagerank.js";
|
|
16
|
+
export { DeltaPageRank, PriorityDeltaPageRank } from "./delta-pagerank.js";
|
|
17
|
+
export type { EigenvectorCentralityOptions } from "./eigenvector.js";
|
|
18
|
+
export { eigenvectorCentrality, nodeEigenvectorCentrality } from "./eigenvector.js";
|
|
19
|
+
export type { HITSOptions, HITSResult } from "./hits.js";
|
|
20
|
+
export { hits, nodeHITS } from "./hits.js";
|
|
21
|
+
export type { KatzCentralityOptions } from "./katz.js";
|
|
22
|
+
export { katzCentrality, nodeKatzCentrality } from "./katz.js";
|
|
23
|
+
export type { PageRankOptions, PageRankResult } from "./pagerank.js";
|
|
24
|
+
export { pageRank, pageRankCentrality, personalizedPageRank, topPageRankNodes } from "./pagerank.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {Graph} from "../../core/graph.js";
|
|
2
|
-
import type {CentralityOptions, CentralityResult} from "../../types/index.js";
|
|
1
|
+
import type { Graph } from "../../core/graph.js";
|
|
2
|
+
import type { CentralityOptions, CentralityResult } from "../../types/index.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Katz centrality implementation
|
|
@@ -22,20 +22,14 @@ export interface KatzCentralityOptions extends CentralityOptions {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
|
-
* Calculate Katz centrality for all nodes in the graph
|
|
26
|
-
* Uses iterative method to compute centrality scores
|
|
25
|
+
* Calculate Katz centrality for all nodes in the graph.
|
|
26
|
+
* Uses iterative method to compute centrality scores.
|
|
27
|
+
* @param graph - The graph to compute Katz centrality on
|
|
28
|
+
* @param options - Configuration options for the computation
|
|
29
|
+
* @returns Object mapping node IDs to their Katz centrality scores
|
|
27
30
|
*/
|
|
28
|
-
export function katzCentrality(
|
|
29
|
-
|
|
30
|
-
options: KatzCentralityOptions = {},
|
|
31
|
-
): CentralityResult {
|
|
32
|
-
const {
|
|
33
|
-
alpha = 0.1,
|
|
34
|
-
beta = 1.0,
|
|
35
|
-
maxIterations = 100,
|
|
36
|
-
tolerance = 1e-6,
|
|
37
|
-
normalized = true,
|
|
38
|
-
} = options;
|
|
31
|
+
export function katzCentrality(graph: Graph, options: KatzCentralityOptions = {}): CentralityResult {
|
|
32
|
+
const { alpha = 0.1, beta = 1.0, maxIterations = 100, tolerance = 1e-6, normalized = true } = options;
|
|
39
33
|
|
|
40
34
|
const centrality: CentralityResult = {};
|
|
41
35
|
const nodes = Array.from(graph.nodes());
|
|
@@ -68,16 +62,14 @@ export function katzCentrality(
|
|
|
68
62
|
|
|
69
63
|
// For directed graphs, use in-neighbors
|
|
70
64
|
// For undirected graphs, use all neighbors
|
|
71
|
-
const neighbors = graph.isDirected ?
|
|
72
|
-
Array.from(graph.inNeighbors(nodeId)) :
|
|
73
|
-
graph.neighbors(nodeId);
|
|
65
|
+
const neighbors = graph.isDirected ? Array.from(graph.inNeighbors(nodeId)) : graph.neighbors(nodeId);
|
|
74
66
|
|
|
75
67
|
for (const neighbor of neighbors) {
|
|
76
68
|
const neighborKey = neighbor.toString();
|
|
77
69
|
sum += previousScores.get(neighborKey) ?? 0;
|
|
78
70
|
}
|
|
79
71
|
|
|
80
|
-
currentScores.set(nodeId.toString(),
|
|
72
|
+
currentScores.set(nodeId.toString(), alpha * sum + beta);
|
|
81
73
|
}
|
|
82
74
|
|
|
83
75
|
// Check for convergence
|
|
@@ -123,13 +115,13 @@ export function katzCentrality(
|
|
|
123
115
|
}
|
|
124
116
|
|
|
125
117
|
/**
|
|
126
|
-
* Calculate Katz centrality for a specific node
|
|
118
|
+
* Calculate Katz centrality for a specific node.
|
|
119
|
+
* @param graph - The graph to compute Katz centrality on
|
|
120
|
+
* @param nodeId - The ID of the node to calculate centrality for
|
|
121
|
+
* @param options - Configuration options for the computation
|
|
122
|
+
* @returns The Katz centrality score for the specified node
|
|
127
123
|
*/
|
|
128
|
-
export function nodeKatzCentrality(
|
|
129
|
-
graph: Graph,
|
|
130
|
-
nodeId: string | number,
|
|
131
|
-
options: KatzCentralityOptions = {},
|
|
132
|
-
): number {
|
|
124
|
+
export function nodeKatzCentrality(graph: Graph, nodeId: string | number, options: KatzCentralityOptions = {}): number {
|
|
133
125
|
if (!graph.hasNode(nodeId)) {
|
|
134
126
|
throw new Error(`Node ${String(nodeId)} not found in graph`);
|
|
135
127
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {Graph} from "../../core/graph.js";
|
|
2
|
-
import type {NodeId} from "../../types/index.js";
|
|
3
|
-
import {SimpleDeltaPageRank} from "./delta-pagerank-simple.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";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* PageRank algorithm implementation
|
|
@@ -76,11 +76,11 @@ export interface PageRankResult {
|
|
|
76
76
|
*
|
|
77
77
|
* For initial computation on small-medium graphs, standard algorithm may be faster
|
|
78
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
|
|
79
82
|
*/
|
|
80
|
-
export function pageRank(
|
|
81
|
-
graph: Graph,
|
|
82
|
-
options: PageRankOptions = {},
|
|
83
|
-
): PageRankResult {
|
|
83
|
+
export function pageRank(graph: Graph, options: PageRankOptions = {}): PageRankResult {
|
|
84
84
|
const {
|
|
85
85
|
dampingFactor = 0.85,
|
|
86
86
|
maxIterations = 100,
|
|
@@ -102,7 +102,7 @@ export function pageRank(
|
|
|
102
102
|
const n = nodes.length;
|
|
103
103
|
|
|
104
104
|
if (n === 0) {
|
|
105
|
-
return {ranks: {}, iterations: 0, converged: true};
|
|
105
|
+
return { ranks: {}, iterations: 0, converged: true };
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
// Use delta-based optimization by default for larger graphs
|
|
@@ -221,7 +221,7 @@ export function pageRank(
|
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
if (danglingSum > 0) {
|
|
224
|
-
const danglingContribution = dampingFactor * danglingSum / n;
|
|
224
|
+
const danglingContribution = (dampingFactor * danglingSum) / n;
|
|
225
225
|
for (const nodeId of nodes) {
|
|
226
226
|
const currentRank = newRanks.get(nodeId) ?? 0;
|
|
227
227
|
if (personalVector) {
|
|
@@ -284,6 +284,10 @@ export function pageRank(
|
|
|
284
284
|
|
|
285
285
|
/**
|
|
286
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
|
|
287
291
|
*/
|
|
288
292
|
export function personalizedPageRank(
|
|
289
293
|
graph: Graph,
|
|
@@ -314,35 +318,39 @@ export function personalizedPageRank(
|
|
|
314
318
|
}
|
|
315
319
|
|
|
316
320
|
return pageRank(graph, {
|
|
317
|
-
...
|
|
321
|
+
...options,
|
|
318
322
|
personalization,
|
|
319
323
|
});
|
|
320
324
|
}
|
|
321
325
|
|
|
322
326
|
/**
|
|
323
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
|
|
324
331
|
*/
|
|
325
|
-
export function pageRankCentrality(
|
|
326
|
-
graph: Graph,
|
|
327
|
-
options: PageRankOptions = {},
|
|
328
|
-
): Record<string, number> {
|
|
332
|
+
export function pageRankCentrality(graph: Graph, options: PageRankOptions = {}): Record<string, number> {
|
|
329
333
|
const result = pageRank(graph, options);
|
|
330
334
|
return result.ranks;
|
|
331
335
|
}
|
|
332
336
|
|
|
333
337
|
/**
|
|
334
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
|
|
335
343
|
*/
|
|
336
344
|
export function topPageRankNodes(
|
|
337
345
|
graph: Graph,
|
|
338
346
|
k: number,
|
|
339
347
|
options: PageRankOptions = {},
|
|
340
|
-
): {node: NodeId
|
|
348
|
+
): { node: NodeId; rank: number }[] {
|
|
341
349
|
const result = pageRank(graph, options);
|
|
342
350
|
|
|
343
|
-
const nodeRanks: {node: NodeId
|
|
351
|
+
const nodeRanks: { node: NodeId; rank: number }[] = [];
|
|
344
352
|
for (const [nodeStr, rank] of Object.entries(result.ranks)) {
|
|
345
|
-
nodeRanks.push({node: nodeStr as NodeId, rank});
|
|
353
|
+
nodeRanks.push({ node: nodeStr as NodeId, rank });
|
|
346
354
|
}
|
|
347
355
|
|
|
348
356
|
// Sort by rank in descending order
|
|
@@ -353,6 +361,7 @@ export function topPageRankNodes(
|
|
|
353
361
|
|
|
354
362
|
/**
|
|
355
363
|
* Normalize ranks so they sum to 1
|
|
364
|
+
* @param ranks - The ranks map to normalize in place
|
|
356
365
|
*/
|
|
357
366
|
function normalizeRanks(ranks: Map<NodeId, number>): void {
|
|
358
367
|
let sum = 0;
|