@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
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seeded random number generator for reproducible results
|
|
3
|
+
*/
|
|
4
|
+
export class SeededRandom {
|
|
5
|
+
private seed: number;
|
|
6
|
+
private readonly m = 0x80000000; // 2**31
|
|
7
|
+
private readonly a = 1103515245;
|
|
8
|
+
private readonly c = 12345;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Creates a new SeededRandom instance with the given seed.
|
|
12
|
+
* @param seed - The seed value for reproducible random number generation
|
|
13
|
+
*/
|
|
14
|
+
constructor(seed: number) {
|
|
15
|
+
// Handle negative seeds correctly
|
|
16
|
+
this.seed = ((seed % this.m) + this.m) % this.m;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Generate next random number between 0 and 1
|
|
21
|
+
* @returns A pseudo-random number in the range [0, 1]
|
|
22
|
+
*/
|
|
23
|
+
next(): number {
|
|
24
|
+
this.seed = (this.a * this.seed + this.c) % this.m;
|
|
25
|
+
return this.seed / (this.m - 1);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Create a generator function for backward compatibility
|
|
30
|
+
* @param seed - The seed value for reproducible random number generation
|
|
31
|
+
* @returns A function that returns the next random number when called
|
|
32
|
+
*/
|
|
33
|
+
static createGenerator(seed: number): () => number {
|
|
34
|
+
const rng = new SeededRandom(seed);
|
|
35
|
+
return () => rng.next();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Fisher-Yates shuffle algorithm
|
|
41
|
+
* @param array - Array to shuffle (will be modified in place)
|
|
42
|
+
* @param rng - Optional random number generator (defaults to Math.random)
|
|
43
|
+
* @returns The shuffled array (same reference as input)
|
|
44
|
+
*/
|
|
45
|
+
export function shuffle<T>(array: T[], rng: () => number = Math.random): T[] {
|
|
46
|
+
for (let i = array.length - 1; i > 0; i--) {
|
|
47
|
+
const j = Math.floor(rng() * (i + 1));
|
|
48
|
+
const temp = array[i];
|
|
49
|
+
const tempJ = array[j];
|
|
50
|
+
if (temp !== undefined && tempJ !== undefined) {
|
|
51
|
+
array[i] = tempJ;
|
|
52
|
+
array[j] = temp;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return array;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Calculate Euclidean distance between two vectors
|
|
60
|
+
* @param a - First vector
|
|
61
|
+
* @param b - Second vector
|
|
62
|
+
* @returns Euclidean distance
|
|
63
|
+
* @throws Error if vectors have different lengths
|
|
64
|
+
*/
|
|
65
|
+
export function euclideanDistance(a: number[], b: number[]): number {
|
|
66
|
+
if (a.length !== b.length) {
|
|
67
|
+
throw new Error("Vectors must have same length");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let sum = 0;
|
|
71
|
+
for (let i = 0; i < a.length; i++) {
|
|
72
|
+
const aVal = a[i];
|
|
73
|
+
const bVal = b[i];
|
|
74
|
+
if (aVal !== undefined && bVal !== undefined) {
|
|
75
|
+
const diff = aVal - bVal;
|
|
76
|
+
sum += diff * diff;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return Math.sqrt(sum);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export const normalize = {
|
|
83
|
+
/**
|
|
84
|
+
* Min-max normalization to [0, 1] range
|
|
85
|
+
* @param values - Map of values to normalize in place
|
|
86
|
+
*/
|
|
87
|
+
minMax(values: Map<string, number>): void {
|
|
88
|
+
const vals = Array.from(values.values());
|
|
89
|
+
const min = Math.min(...vals);
|
|
90
|
+
const max = Math.max(...vals);
|
|
91
|
+
const range = max - min;
|
|
92
|
+
|
|
93
|
+
if (range === 0) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
for (const [key, value] of values) {
|
|
98
|
+
values.set(key, (value - min) / range);
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Normalize by maximum value
|
|
104
|
+
* @param values - Map of values to normalize in place
|
|
105
|
+
*/
|
|
106
|
+
byMax(values: Map<string, number>): void {
|
|
107
|
+
const max = Math.max(...values.values());
|
|
108
|
+
if (max === 0) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
for (const [key, value] of values) {
|
|
113
|
+
values.set(key, value / max);
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* L2 (Euclidean) normalization
|
|
119
|
+
* @param values - Map of values to normalize in place
|
|
120
|
+
*/
|
|
121
|
+
l2Norm(values: Map<string, number>): void {
|
|
122
|
+
const sumSquares = Array.from(values.values()).reduce((sum, val) => sum + val * val, 0);
|
|
123
|
+
const norm = Math.sqrt(sumSquares);
|
|
124
|
+
|
|
125
|
+
if (norm === 0) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
for (const [key, value] of values) {
|
|
130
|
+
values.set(key, value / norm);
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Normalize to sum to 1
|
|
136
|
+
* @param values - Map of values to normalize in place
|
|
137
|
+
*/
|
|
138
|
+
sumToOne(values: Map<string, number>): void {
|
|
139
|
+
const sum = Array.from(values.values()).reduce((acc, val) => acc + val, 0);
|
|
140
|
+
|
|
141
|
+
if (sum === 0) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
for (const [key, value] of values) {
|
|
146
|
+
values.set(key, value / sum);
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { Graph } from "../core/graph.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Common interface for algorithm options with optimization support
|
|
5
|
+
*/
|
|
6
|
+
export interface OptimizableOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Whether to use optimized implementations
|
|
9
|
+
* - true: Force use of optimizations
|
|
10
|
+
* - false: Disable optimizations
|
|
11
|
+
* - "auto": Automatically decide based on graph size (default)
|
|
12
|
+
*/
|
|
13
|
+
optimized?: boolean | "auto";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Check if a graph should use optimizations based on its size
|
|
18
|
+
* @param nodeCount - The number of nodes in the graph
|
|
19
|
+
* @param edgeCount - The number of edges in the graph
|
|
20
|
+
* @returns True if the graph is large enough to benefit from optimizations
|
|
21
|
+
*/
|
|
22
|
+
function shouldUseOptimizations(nodeCount: number, edgeCount: number): boolean {
|
|
23
|
+
// Use optimizations for graphs with more than 10k nodes or 100k edges
|
|
24
|
+
return nodeCount > 10000 || edgeCount > 100000;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Determine if optimizations should be used for a given graph
|
|
29
|
+
* @param graph - The graph to check for optimization eligibility
|
|
30
|
+
* @param options - Options containing the optimization preference
|
|
31
|
+
* @returns True if optimizations should be used for this graph
|
|
32
|
+
*/
|
|
33
|
+
export function shouldOptimize(graph: Graph, options: OptimizableOptions = {}): boolean {
|
|
34
|
+
const { optimized = "auto" } = options;
|
|
35
|
+
|
|
36
|
+
if (optimized === "auto") {
|
|
37
|
+
// Check graph size
|
|
38
|
+
return shouldUseOptimizations(graph.nodeCount, graph.totalEdgeCount);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return optimized;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Merge optimization options with algorithm-specific options
|
|
46
|
+
* @param graph - The graph to determine optimization settings for
|
|
47
|
+
* @param options - Algorithm options that may include optimization settings
|
|
48
|
+
* @returns The options with resolved optimization boolean flag
|
|
49
|
+
*/
|
|
50
|
+
export function mergeOptimizationOptions<T extends Record<string, unknown>>(
|
|
51
|
+
graph: Graph,
|
|
52
|
+
options: T & OptimizableOptions,
|
|
53
|
+
): T & { optimized?: boolean } {
|
|
54
|
+
const { optimized: userOptimized, ...rest } = options;
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
...rest,
|
|
58
|
+
optimized: shouldOptimize(graph, userOptimized !== undefined ? { optimized: userOptimized } : {}),
|
|
59
|
+
} as T & { optimized?: boolean };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Create an optimized version of an algorithm
|
|
64
|
+
* @param algorithm - The algorithm function to wrap with optimization support
|
|
65
|
+
* @param optionsTransformer - Optional function to transform options before passing to the algorithm
|
|
66
|
+
* @returns A wrapped version of the algorithm that applies optimization transformations
|
|
67
|
+
* @example
|
|
68
|
+
* const optimizedBetweenness = createOptimizedAlgorithm(
|
|
69
|
+
* betweennessCentrality,
|
|
70
|
+
* (graph, options) => ({...options, optimized: true})
|
|
71
|
+
* );
|
|
72
|
+
*/
|
|
73
|
+
export function createOptimizedAlgorithm<TArgs extends [Graph, ...unknown[]], TResult>(
|
|
74
|
+
algorithm: (...args: TArgs) => TResult,
|
|
75
|
+
optionsTransformer?: (graph: Graph, options: unknown) => unknown,
|
|
76
|
+
): (...args: TArgs) => TResult {
|
|
77
|
+
return (...args: TArgs): TResult => {
|
|
78
|
+
const [graph, options, ...rest] = args;
|
|
79
|
+
|
|
80
|
+
if (optionsTransformer && options !== undefined) {
|
|
81
|
+
const transformedOptions = optionsTransformer(graph, options);
|
|
82
|
+
return algorithm(...([graph, transformedOptions, ...rest] as unknown as TArgs));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return algorithm(...args);
|
|
86
|
+
};
|
|
87
|
+
}
|
|
@@ -5,13 +5,17 @@ export class MinPriorityQueue<T> {
|
|
|
5
5
|
private heap: T[] = [];
|
|
6
6
|
private compare: (a: T, b: T) => number;
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Creates a new MinPriorityQueue instance.
|
|
10
|
+
* @param compareFunction - Custom comparison function. Returns negative if a has higher priority than b.
|
|
11
|
+
*/
|
|
8
12
|
constructor(compareFunction?: (a: T, b: T) => number) {
|
|
9
13
|
this.compare = compareFunction ?? ((a: T, b: T) => this.defaultCompare(a, b));
|
|
10
14
|
}
|
|
11
15
|
|
|
12
16
|
private defaultCompare(a: T, b: T): number {
|
|
13
|
-
const aWithDistance = a as T & {distance?: number};
|
|
14
|
-
const bWithDistance = b as T & {distance?: number};
|
|
17
|
+
const aWithDistance = a as T & { distance?: number };
|
|
18
|
+
const bWithDistance = b as T & { distance?: number };
|
|
15
19
|
|
|
16
20
|
if (aWithDistance.distance !== undefined && bWithDistance.distance !== undefined) {
|
|
17
21
|
return aWithDistance.distance - bWithDistance.distance;
|
|
@@ -25,11 +29,11 @@ export class MinPriorityQueue<T> {
|
|
|
25
29
|
}
|
|
26
30
|
|
|
27
31
|
private leftChild(i: number): number {
|
|
28
|
-
return
|
|
32
|
+
return 2 * i + 1;
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
private rightChild(i: number): number {
|
|
32
|
-
return
|
|
36
|
+
return 2 * i + 2;
|
|
33
37
|
}
|
|
34
38
|
|
|
35
39
|
private swap(i: number, j: number): void {
|
|
@@ -63,13 +67,23 @@ export class MinPriorityQueue<T> {
|
|
|
63
67
|
|
|
64
68
|
const leftItem = this.heap[left];
|
|
65
69
|
const minItem = this.heap[minIndex];
|
|
66
|
-
if (
|
|
70
|
+
if (
|
|
71
|
+
left < this.heap.length &&
|
|
72
|
+
leftItem !== undefined &&
|
|
73
|
+
minItem !== undefined &&
|
|
74
|
+
this.compare(leftItem, minItem) < 0
|
|
75
|
+
) {
|
|
67
76
|
minIndex = left;
|
|
68
77
|
}
|
|
69
78
|
|
|
70
79
|
const rightItem = this.heap[right];
|
|
71
80
|
const newMinItem = this.heap[minIndex];
|
|
72
|
-
if (
|
|
81
|
+
if (
|
|
82
|
+
right < this.heap.length &&
|
|
83
|
+
rightItem !== undefined &&
|
|
84
|
+
newMinItem !== undefined &&
|
|
85
|
+
this.compare(rightItem, newMinItem) < 0
|
|
86
|
+
) {
|
|
73
87
|
minIndex = right;
|
|
74
88
|
}
|
|
75
89
|
|
|
@@ -82,11 +96,19 @@ export class MinPriorityQueue<T> {
|
|
|
82
96
|
}
|
|
83
97
|
}
|
|
84
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Insert a value into the priority queue.
|
|
101
|
+
* @param value - The value to insert
|
|
102
|
+
*/
|
|
85
103
|
insert(value: T): void {
|
|
86
104
|
this.heap.push(value);
|
|
87
105
|
this.heapifyUp(this.heap.length - 1);
|
|
88
106
|
}
|
|
89
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Remove and return the minimum value from the priority queue.
|
|
110
|
+
* @returns The minimum value, or undefined if the queue is empty
|
|
111
|
+
*/
|
|
90
112
|
extractMin(): T | undefined {
|
|
91
113
|
if (this.heap.length === 0) {
|
|
92
114
|
return undefined;
|
|
@@ -106,14 +128,26 @@ export class MinPriorityQueue<T> {
|
|
|
106
128
|
return min;
|
|
107
129
|
}
|
|
108
130
|
|
|
131
|
+
/**
|
|
132
|
+
* View the minimum value without removing it.
|
|
133
|
+
* @returns The minimum value, or undefined if the queue is empty
|
|
134
|
+
*/
|
|
109
135
|
peek(): T | undefined {
|
|
110
136
|
return this.heap[0];
|
|
111
137
|
}
|
|
112
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Check if the priority queue is empty.
|
|
141
|
+
* @returns True if the queue has no items, false otherwise
|
|
142
|
+
*/
|
|
113
143
|
isEmpty(): boolean {
|
|
114
144
|
return this.heap.length === 0;
|
|
115
145
|
}
|
|
116
146
|
|
|
147
|
+
/**
|
|
148
|
+
* Get the number of items in the priority queue.
|
|
149
|
+
* @returns The number of items currently in the queue
|
|
150
|
+
*/
|
|
117
151
|
size(): number {
|
|
118
152
|
return this.heap.length;
|
|
119
153
|
}
|