@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,6 +1,6 @@
|
|
|
1
|
-
import {bfsAugmentingPath} from "../algorithms/traversal/bfs-variants.js";
|
|
2
|
-
import type {Graph} from "../core/graph.js";
|
|
3
|
-
import {graphToMap} from "../utils/graph-converters.js";
|
|
1
|
+
import { bfsAugmentingPath } from "../algorithms/traversal/bfs-variants.js";
|
|
2
|
+
import type { Graph } from "../core/graph.js";
|
|
3
|
+
import { graphToMap } from "../utils/graph-converters.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Ford-Fulkerson Algorithm for Maximum Flow
|
|
@@ -24,15 +24,15 @@ export interface FlowNetwork {
|
|
|
24
24
|
export interface MaxFlowResult {
|
|
25
25
|
maxFlow: number;
|
|
26
26
|
flowGraph: Map<string, Map<string, number>>;
|
|
27
|
-
minCut?: {source: Set<string
|
|
27
|
+
minCut?: { source: Set<string>; sink: Set<string>; edges: [string, string][] };
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Create residual graph from original graph
|
|
32
|
+
* @param graph - The original graph with capacity values
|
|
33
|
+
* @returns A residual graph initialized with the original capacities
|
|
32
34
|
*/
|
|
33
|
-
function createResidualGraph(
|
|
34
|
-
graph: Map<string, Map<string, number>>,
|
|
35
|
-
): Map<string, Map<string, number>> {
|
|
35
|
+
function createResidualGraph(graph: Map<string, Map<string, number>>): Map<string, Map<string, number>> {
|
|
36
36
|
const residual = new Map<string, Map<string, number>>();
|
|
37
37
|
|
|
38
38
|
for (const [u, neighbors] of graph) {
|
|
@@ -50,6 +50,10 @@ function createResidualGraph(
|
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
52
|
* Find augmenting path using DFS
|
|
53
|
+
* @param residualGraph - The residual graph with remaining capacities
|
|
54
|
+
* @param source - The source node
|
|
55
|
+
* @param sink - The sink node
|
|
56
|
+
* @returns An array of nodes forming the path, or null if no path exists
|
|
53
57
|
*/
|
|
54
58
|
function findAugmentingPathDFS(
|
|
55
59
|
residualGraph: Map<string, Map<string, number>>,
|
|
@@ -92,6 +96,11 @@ function findAugmentingPathDFS(
|
|
|
92
96
|
|
|
93
97
|
/**
|
|
94
98
|
* Update flow along an augmenting path
|
|
99
|
+
* @param residualGraph - The residual graph to update
|
|
100
|
+
* @param flowGraph - The flow graph to update with new flow values
|
|
101
|
+
* @param originalGraph - The original graph for edge direction reference
|
|
102
|
+
* @param path - The augmenting path to update flow along
|
|
103
|
+
* @param pathFlow - The amount of flow to push through the path
|
|
95
104
|
*/
|
|
96
105
|
function updateFlow(
|
|
97
106
|
residualGraph: Map<string, Map<string, number>>,
|
|
@@ -146,11 +155,14 @@ function updateFlow(
|
|
|
146
155
|
|
|
147
156
|
/**
|
|
148
157
|
* Find minimum cut from source side
|
|
158
|
+
* @param residualGraph - The residual graph after max flow computation
|
|
159
|
+
* @param source - The source node
|
|
160
|
+
* @returns The minimum cut partition with source and sink sets and cut edges
|
|
149
161
|
*/
|
|
150
162
|
function findMinCut(
|
|
151
163
|
residualGraph: Map<string, Map<string, number>>,
|
|
152
164
|
source: string,
|
|
153
|
-
): {source: Set<string
|
|
165
|
+
): { source: Set<string>; sink: Set<string>; edges: [string, string][] } {
|
|
154
166
|
// Find all reachable nodes from source in residual graph
|
|
155
167
|
const sourceSet = new Set<string>();
|
|
156
168
|
const queue = [source];
|
|
@@ -195,20 +207,29 @@ function findMinCut(
|
|
|
195
207
|
}
|
|
196
208
|
}
|
|
197
209
|
|
|
198
|
-
return {source: sourceSet, sink: sinkSet, edges: cutEdges};
|
|
210
|
+
return { source: sourceSet, sink: sinkSet, edges: cutEdges };
|
|
199
211
|
}
|
|
200
212
|
|
|
201
213
|
/**
|
|
202
214
|
* Core max flow algorithm implementation
|
|
215
|
+
* @param graph - The graph with capacity values
|
|
216
|
+
* @param source - The source node
|
|
217
|
+
* @param sink - The sink node
|
|
218
|
+
* @param findPath - Function to find an augmenting path in the residual graph
|
|
219
|
+
* @returns The maximum flow result including flow value, flow graph, and minimum cut
|
|
203
220
|
*/
|
|
204
221
|
function maxFlowCore(
|
|
205
222
|
graph: Map<string, Map<string, number>>,
|
|
206
223
|
source: string,
|
|
207
224
|
sink: string,
|
|
208
|
-
findPath: (
|
|
225
|
+
findPath: (
|
|
226
|
+
residual: Map<string, Map<string, number>>,
|
|
227
|
+
src: string,
|
|
228
|
+
snk: string,
|
|
229
|
+
) => { path: string[]; pathCapacity: number } | null,
|
|
209
230
|
): MaxFlowResult {
|
|
210
231
|
if (!graph.has(source) || !graph.has(sink)) {
|
|
211
|
-
return {maxFlow: 0, flowGraph: new Map()};
|
|
232
|
+
return { maxFlow: 0, flowGraph: new Map() };
|
|
212
233
|
}
|
|
213
234
|
|
|
214
235
|
// Create residual graph
|
|
@@ -230,7 +251,7 @@ function maxFlowCore(
|
|
|
230
251
|
let pathResult = findPath(residualGraph, source, sink);
|
|
231
252
|
|
|
232
253
|
while (pathResult !== null) {
|
|
233
|
-
const {path, pathCapacity} = pathResult;
|
|
254
|
+
const { path, pathCapacity } = pathResult;
|
|
234
255
|
|
|
235
256
|
// Update flow
|
|
236
257
|
updateFlow(residualGraph, flowGraph, graph, path, pathCapacity);
|
|
@@ -243,19 +264,23 @@ function maxFlowCore(
|
|
|
243
264
|
// Find minimum cut
|
|
244
265
|
const minCut = findMinCut(residualGraph, source);
|
|
245
266
|
|
|
246
|
-
return {maxFlow, flowGraph, minCut};
|
|
267
|
+
return { maxFlow, flowGraph, minCut };
|
|
247
268
|
}
|
|
248
269
|
|
|
249
270
|
/**
|
|
250
271
|
* Internal implementation of Ford-Fulkerson algorithm using DFS
|
|
272
|
+
* @param graph - The graph with capacity values
|
|
273
|
+
* @param source - The source node
|
|
274
|
+
* @param sink - The sink node
|
|
275
|
+
* @returns The maximum flow result
|
|
251
276
|
*/
|
|
252
|
-
function fordFulkersonImpl(
|
|
253
|
-
graph: Map<string, Map<string, number>>,
|
|
254
|
-
source: string,
|
|
255
|
-
sink: string,
|
|
256
|
-
): MaxFlowResult {
|
|
277
|
+
function fordFulkersonImpl(graph: Map<string, Map<string, number>>, source: string, sink: string): MaxFlowResult {
|
|
257
278
|
// Adapter function for DFS path finding
|
|
258
|
-
const findPathDFS = (
|
|
279
|
+
const findPathDFS = (
|
|
280
|
+
residual: Map<string, Map<string, number>>,
|
|
281
|
+
src: string,
|
|
282
|
+
snk: string,
|
|
283
|
+
): { path: string[]; pathCapacity: number } | null => {
|
|
259
284
|
const path = findAugmentingPathDFS(residual, src, snk);
|
|
260
285
|
if (!path) {
|
|
261
286
|
return null;
|
|
@@ -274,7 +299,7 @@ function fordFulkersonImpl(
|
|
|
274
299
|
}
|
|
275
300
|
}
|
|
276
301
|
|
|
277
|
-
return {path, pathCapacity};
|
|
302
|
+
return { path, pathCapacity };
|
|
278
303
|
};
|
|
279
304
|
|
|
280
305
|
return maxFlowCore(graph, source, sink, findPathDFS);
|
|
@@ -282,14 +307,18 @@ function fordFulkersonImpl(
|
|
|
282
307
|
|
|
283
308
|
/**
|
|
284
309
|
* Internal implementation of Edmonds-Karp algorithm
|
|
310
|
+
* @param graph - The graph with capacity values
|
|
311
|
+
* @param source - The source node
|
|
312
|
+
* @param sink - The sink node
|
|
313
|
+
* @returns The maximum flow result
|
|
285
314
|
*/
|
|
286
|
-
function edmondsKarpImpl(
|
|
287
|
-
graph: Map<string, Map<string, number>>,
|
|
288
|
-
source: string,
|
|
289
|
-
sink: string,
|
|
290
|
-
): MaxFlowResult {
|
|
315
|
+
function edmondsKarpImpl(graph: Map<string, Map<string, number>>, source: string, sink: string): MaxFlowResult {
|
|
291
316
|
// Use BFS variant for path finding
|
|
292
|
-
const findPathBFS = (
|
|
317
|
+
const findPathBFS = (
|
|
318
|
+
residual: Map<string, Map<string, number>>,
|
|
319
|
+
src: string,
|
|
320
|
+
snk: string,
|
|
321
|
+
): { path: string[]; pathCapacity: number } | null => {
|
|
293
322
|
return bfsAugmentingPath(residual, src, snk);
|
|
294
323
|
};
|
|
295
324
|
|
|
@@ -298,12 +327,16 @@ function edmondsKarpImpl(
|
|
|
298
327
|
|
|
299
328
|
/**
|
|
300
329
|
* Utility function to create a flow network for bipartite matching
|
|
330
|
+
* @param leftNodes - Array of left partition node identifiers
|
|
331
|
+
* @param rightNodes - Array of right partition node identifiers
|
|
332
|
+
* @param edges - Array of edges connecting left nodes to right nodes
|
|
333
|
+
* @returns The flow network graph with source and sink nodes
|
|
301
334
|
*/
|
|
302
335
|
export function createBipartiteFlowNetwork(
|
|
303
336
|
leftNodes: string[],
|
|
304
337
|
rightNodes: string[],
|
|
305
338
|
edges: [string, string][],
|
|
306
|
-
): {graph: Map<string, Map<string, number
|
|
339
|
+
): { graph: Map<string, Map<string, number>>; source: string; sink: string } {
|
|
307
340
|
const graph = new Map<string, Map<string, number>>();
|
|
308
341
|
const source = "__source__";
|
|
309
342
|
const sink = "__sink__";
|
|
@@ -345,12 +378,11 @@ export function createBipartiteFlowNetwork(
|
|
|
345
378
|
|
|
346
379
|
graph.set(sink, new Map());
|
|
347
380
|
|
|
348
|
-
return {graph, source, sink};
|
|
381
|
+
return { graph, source, sink };
|
|
349
382
|
}
|
|
350
383
|
|
|
351
384
|
/**
|
|
352
385
|
* Ford-Fulkerson algorithm using DFS for finding augmenting paths
|
|
353
|
-
*
|
|
354
386
|
* @param graph - Adjacency list representation with capacities - accepts Graph class or Map
|
|
355
387
|
* @param source - Source node
|
|
356
388
|
* @param sink - Sink node
|
|
@@ -359,11 +391,7 @@ export function createBipartiteFlowNetwork(
|
|
|
359
391
|
* Time Complexity: O(E * f) where f is the maximum flow
|
|
360
392
|
* Space Complexity: O(V + E)
|
|
361
393
|
*/
|
|
362
|
-
export function fordFulkerson(
|
|
363
|
-
graph: Graph,
|
|
364
|
-
source: string,
|
|
365
|
-
sink: string,
|
|
366
|
-
): MaxFlowResult {
|
|
394
|
+
export function fordFulkerson(graph: Graph, source: string, sink: string): MaxFlowResult {
|
|
367
395
|
// Convert Graph to Map representation
|
|
368
396
|
const graphMap = graphToMap(graph);
|
|
369
397
|
return fordFulkersonImpl(graphMap, source, sink);
|
|
@@ -372,7 +400,6 @@ export function fordFulkerson(
|
|
|
372
400
|
/**
|
|
373
401
|
* Edmonds-Karp algorithm (Ford-Fulkerson with BFS)
|
|
374
402
|
* More efficient implementation with better time complexity
|
|
375
|
-
*
|
|
376
403
|
* @param graph - Adjacency list representation with capacities - accepts Graph class or Map
|
|
377
404
|
* @param source - Source node
|
|
378
405
|
* @param sink - Sink node
|
package/src/flow/min-cut.ts
CHANGED
|
@@ -4,21 +4,20 @@
|
|
|
4
4
|
* Various algorithms for finding minimum cuts in graphs
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type {Graph} from "../core/graph.js";
|
|
8
|
-
import {graphToMap} from "../utils/graph-converters.js";
|
|
9
|
-
import {fordFulkerson} from "./ford-fulkerson.js";
|
|
7
|
+
import type { Graph } from "../core/graph.js";
|
|
8
|
+
import { graphToMap } from "../utils/graph-converters.js";
|
|
9
|
+
import { fordFulkerson } from "./ford-fulkerson.js";
|
|
10
10
|
|
|
11
11
|
export interface MinCutResult {
|
|
12
12
|
cutValue: number;
|
|
13
13
|
partition1: Set<string>;
|
|
14
14
|
partition2: Set<string>;
|
|
15
|
-
cutEdges: {from: string
|
|
15
|
+
cutEdges: { from: string; to: string; weight: number }[];
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Find minimum s-t cut using max flow
|
|
20
20
|
* The minimum cut value equals the maximum flow value (max-flow min-cut theorem)
|
|
21
|
-
*
|
|
22
21
|
* @param graph - Weighted graph
|
|
23
22
|
* @param source - Source node
|
|
24
23
|
* @param sink - Sink node
|
|
@@ -26,11 +25,7 @@ export interface MinCutResult {
|
|
|
26
25
|
*
|
|
27
26
|
* Time Complexity: Same as max flow algorithm used
|
|
28
27
|
*/
|
|
29
|
-
export function minSTCut(
|
|
30
|
-
graph: Graph,
|
|
31
|
-
source: string,
|
|
32
|
-
sink: string,
|
|
33
|
-
): MinCutResult {
|
|
28
|
+
export function minSTCut(graph: Graph, source: string, sink: string): MinCutResult {
|
|
34
29
|
const flowResult = fordFulkerson(graph, source, sink);
|
|
35
30
|
|
|
36
31
|
if (!flowResult.minCut) {
|
|
@@ -42,14 +37,14 @@ export function minSTCut(
|
|
|
42
37
|
};
|
|
43
38
|
}
|
|
44
39
|
|
|
45
|
-
const cutEdges: {from: string
|
|
40
|
+
const cutEdges: { from: string; to: string; weight: number }[] = [];
|
|
46
41
|
|
|
47
42
|
// Find actual cut edges and their weights
|
|
48
43
|
for (const [u, v] of flowResult.minCut.edges) {
|
|
49
44
|
const edge = graph.getEdge(u, v);
|
|
50
45
|
const weight = edge?.weight ?? 0;
|
|
51
46
|
if (weight > 0) {
|
|
52
|
-
cutEdges.push({from: u, to: v, weight});
|
|
47
|
+
cutEdges.push({ from: u, to: v, weight });
|
|
53
48
|
}
|
|
54
49
|
}
|
|
55
50
|
|
|
@@ -64,15 +59,12 @@ export function minSTCut(
|
|
|
64
59
|
/**
|
|
65
60
|
* Stoer-Wagner algorithm for finding global minimum cut
|
|
66
61
|
* Finds the minimum cut that separates the graph into two parts
|
|
67
|
-
*
|
|
68
62
|
* @param graph - Undirected weighted graph - accepts Graph class or Map representation
|
|
69
63
|
* @returns Global minimum cut
|
|
70
64
|
*
|
|
71
65
|
* Time Complexity: O(V³) or O(VE + V² log V) with heap
|
|
72
66
|
*/
|
|
73
|
-
export function stoerWagner(
|
|
74
|
-
graph: Graph | Map<string, Map<string, number>>,
|
|
75
|
-
): MinCutResult {
|
|
67
|
+
export function stoerWagner(graph: Graph | Map<string, Map<string, number>>): MinCutResult {
|
|
76
68
|
// Convert Graph to Map representation if needed
|
|
77
69
|
const graphMap = graph instanceof Map ? graph : graphToMap(graph);
|
|
78
70
|
// Convert to undirected if necessary
|
|
@@ -140,13 +132,13 @@ export function stoerWagner(
|
|
|
140
132
|
}
|
|
141
133
|
|
|
142
134
|
// Find cut edges
|
|
143
|
-
const cutEdges: {from: string
|
|
135
|
+
const cutEdges: { from: string; to: string; weight: number }[] = [];
|
|
144
136
|
for (const u of partition1) {
|
|
145
137
|
const neighbors = originalGraph.get(u);
|
|
146
138
|
if (neighbors) {
|
|
147
139
|
for (const [v, weight] of neighbors) {
|
|
148
140
|
if (partition2.has(v)) {
|
|
149
|
-
cutEdges.push({from: u, to: v, weight});
|
|
141
|
+
cutEdges.push({ from: u, to: v, weight });
|
|
150
142
|
}
|
|
151
143
|
}
|
|
152
144
|
}
|
|
@@ -162,11 +154,14 @@ export function stoerWagner(
|
|
|
162
154
|
|
|
163
155
|
/**
|
|
164
156
|
* Minimum cut phase of Stoer-Wagner algorithm
|
|
157
|
+
* @param graph - The undirected weighted graph
|
|
158
|
+
* @param nodes - Array of remaining nodes in the graph
|
|
159
|
+
* @returns The cut result with last two nodes, cut value, and partition
|
|
165
160
|
*/
|
|
166
161
|
function minimumCutPhase(
|
|
167
162
|
graph: Map<string, Map<string, number>>,
|
|
168
163
|
nodes: string[],
|
|
169
|
-
): {s: string
|
|
164
|
+
): { s: string; t: string; value: number; partition: string[] } {
|
|
170
165
|
const n = nodes.length;
|
|
171
166
|
const weight = new Map<string, number>();
|
|
172
167
|
const added = new Set<string>();
|
|
@@ -180,7 +175,7 @@ function minimumCutPhase(
|
|
|
180
175
|
// Start with arbitrary node
|
|
181
176
|
let lastAdded = nodes[0];
|
|
182
177
|
if (!lastAdded) {
|
|
183
|
-
return {s: "", t: "", value: 0, partition: []};
|
|
178
|
+
return { s: "", t: "", value: 0, partition: [] };
|
|
184
179
|
}
|
|
185
180
|
|
|
186
181
|
added.add(lastAdded);
|
|
@@ -188,7 +183,7 @@ function minimumCutPhase(
|
|
|
188
183
|
|
|
189
184
|
// Add remaining nodes
|
|
190
185
|
for (let i = 1; i < n; i++) {
|
|
191
|
-
|
|
186
|
+
// Update weights
|
|
192
187
|
if (!lastAdded) {
|
|
193
188
|
continue;
|
|
194
189
|
}
|
|
@@ -225,7 +220,7 @@ function minimumCutPhase(
|
|
|
225
220
|
const s = order[order.length - 2];
|
|
226
221
|
const t = order[order.length - 1];
|
|
227
222
|
if (!s || !t) {
|
|
228
|
-
return {s: "", t: "", value: 0, partition: []};
|
|
223
|
+
return { s: "", t: "", value: 0, partition: [] };
|
|
229
224
|
}
|
|
230
225
|
|
|
231
226
|
const cutValue = weight.get(t) ?? 0;
|
|
@@ -233,18 +228,17 @@ function minimumCutPhase(
|
|
|
233
228
|
// Partition is all nodes except t
|
|
234
229
|
const partition = order.slice(0, -1);
|
|
235
230
|
|
|
236
|
-
return {s, t, value: cutValue, partition};
|
|
231
|
+
return { s, t, value: cutValue, partition };
|
|
237
232
|
}
|
|
238
233
|
|
|
239
234
|
/**
|
|
240
235
|
* Contract two nodes in the graph
|
|
236
|
+
* @param graph - The graph to modify by contracting nodes
|
|
237
|
+
* @param nodes - Array of nodes to update after contraction
|
|
238
|
+
* @param s - The node to keep after contraction
|
|
239
|
+
* @param t - The node to merge into s
|
|
241
240
|
*/
|
|
242
|
-
function contractNodes(
|
|
243
|
-
graph: Map<string, Map<string, number>>,
|
|
244
|
-
nodes: string[],
|
|
245
|
-
s: string,
|
|
246
|
-
t: string,
|
|
247
|
-
): void {
|
|
241
|
+
function contractNodes(graph: Map<string, Map<string, number>>, nodes: string[], s: string, t: string): void {
|
|
248
242
|
// Merge t into s
|
|
249
243
|
const sNeighbors = graph.get(s);
|
|
250
244
|
const tNeighbors = graph.get(t);
|
|
@@ -279,10 +273,10 @@ function contractNodes(
|
|
|
279
273
|
|
|
280
274
|
/**
|
|
281
275
|
* Convert directed graph to undirected
|
|
276
|
+
* @param graph - The directed graph to convert
|
|
277
|
+
* @returns An undirected graph with edges in both directions
|
|
282
278
|
*/
|
|
283
|
-
function makeUndirected(
|
|
284
|
-
graph: Map<string, Map<string, number>>,
|
|
285
|
-
): Map<string, Map<string, number>> {
|
|
279
|
+
function makeUndirected(graph: Map<string, Map<string, number>>): Map<string, Map<string, number>> {
|
|
286
280
|
const undirected = new Map<string, Map<string, number>>();
|
|
287
281
|
|
|
288
282
|
// Initialize all nodes
|
|
@@ -315,17 +309,13 @@ function makeUndirected(
|
|
|
315
309
|
/**
|
|
316
310
|
* Karger's randomized min-cut algorithm
|
|
317
311
|
* Probabilistic algorithm that finds min cut with high probability
|
|
318
|
-
*
|
|
319
312
|
* @param graph - Undirected graph - accepts Graph class or Map representation
|
|
320
313
|
* @param iterations - Number of iterations (higher = better accuracy)
|
|
321
314
|
* @returns Minimum cut found
|
|
322
315
|
*
|
|
323
316
|
* Time Complexity: O(V² * iterations)
|
|
324
317
|
*/
|
|
325
|
-
export function kargerMinCut(
|
|
326
|
-
graph: Graph | Map<string, Map<string, number>>,
|
|
327
|
-
iterations = 100,
|
|
328
|
-
): MinCutResult {
|
|
318
|
+
export function kargerMinCut(graph: Graph | Map<string, Map<string, number>>, iterations = 100): MinCutResult {
|
|
329
319
|
// Convert Graph to Map representation if needed
|
|
330
320
|
const graphMap = graph instanceof Map ? graph : graphToMap(graph);
|
|
331
321
|
let minCutValue = Infinity;
|
|
@@ -343,13 +333,13 @@ export function kargerMinCut(
|
|
|
343
333
|
}
|
|
344
334
|
|
|
345
335
|
// Find cut edges
|
|
346
|
-
const cutEdges: {from: string
|
|
336
|
+
const cutEdges: { from: string; to: string; weight: number }[] = [];
|
|
347
337
|
for (const u of bestPartition1) {
|
|
348
338
|
const neighbors = graphMap.get(u);
|
|
349
339
|
if (neighbors) {
|
|
350
340
|
for (const [v, weight] of neighbors) {
|
|
351
341
|
if (bestPartition2.has(v)) {
|
|
352
|
-
cutEdges.push({from: u, to: v, weight});
|
|
342
|
+
cutEdges.push({ from: u, to: v, weight });
|
|
353
343
|
}
|
|
354
344
|
}
|
|
355
345
|
}
|
|
@@ -365,10 +355,14 @@ export function kargerMinCut(
|
|
|
365
355
|
|
|
366
356
|
/**
|
|
367
357
|
* Single run of Karger's algorithm
|
|
358
|
+
* @param graph - The undirected weighted graph
|
|
359
|
+
* @returns The cut result with cut value and two partitions
|
|
368
360
|
*/
|
|
369
|
-
function kargerSingleRun(
|
|
370
|
-
|
|
371
|
-
|
|
361
|
+
function kargerSingleRun(graph: Map<string, Map<string, number>>): {
|
|
362
|
+
cutValue: number;
|
|
363
|
+
partition1: Set<string>;
|
|
364
|
+
partition2: Set<string>;
|
|
365
|
+
} {
|
|
372
366
|
// Create a copy of the graph
|
|
373
367
|
const workGraph = new Map<string, Map<string, number>>();
|
|
374
368
|
const superNodes = new Map<string, Set<string>>();
|
|
@@ -381,11 +375,12 @@ function kargerSingleRun(
|
|
|
381
375
|
|
|
382
376
|
// Contract until 2 nodes remain
|
|
383
377
|
while (workGraph.size > 2) {
|
|
384
|
-
|
|
378
|
+
// Pick random edge
|
|
385
379
|
const edges: [string, string, number][] = [];
|
|
386
380
|
for (const [u, neighbors] of workGraph) {
|
|
387
381
|
for (const [v, weight] of neighbors) {
|
|
388
|
-
if (u < v) {
|
|
382
|
+
if (u < v) {
|
|
383
|
+
// Avoid duplicates
|
|
389
384
|
edges.push([u, v, weight]);
|
|
390
385
|
}
|
|
391
386
|
}
|
|
@@ -440,6 +435,10 @@ function kargerSingleRun(
|
|
|
440
435
|
|
|
441
436
|
/**
|
|
442
437
|
* Contract edge in Karger's algorithm
|
|
438
|
+
* @param graph - The working graph to modify
|
|
439
|
+
* @param superNodes - Map tracking which original nodes are in each super node
|
|
440
|
+
* @param u - First endpoint of the edge to contract
|
|
441
|
+
* @param v - Second endpoint of the edge to contract (merged into u)
|
|
443
442
|
*/
|
|
444
443
|
function contractKarger(
|
|
445
444
|
graph: Map<string, Map<string, number>>,
|
|
@@ -489,4 +488,3 @@ function contractKarger(
|
|
|
489
488
|
graph.delete(v);
|
|
490
489
|
superNodes.delete(v);
|
|
491
490
|
}
|
|
492
|
-
|
package/src/index.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* graphty/algorithms - Graph algorithms library for browser environments
|
|
3
3
|
*
|
|
4
4
|
* A comprehensive TypeScript library implementing fundamental graph algorithms
|
|
5
5
|
* optimized for browser environments and visualization applications.
|
|
6
|
+
* @module
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
9
|
// Core exports
|
|
9
|
-
export {Graph} from "./core/graph.js";
|
|
10
|
+
export { Graph } from "./core/graph.js";
|
|
10
11
|
|
|
11
12
|
// Type exports
|
|
12
13
|
export type {
|