Skip to content

Commit 76dd412

Browse files
Implement the optimal stack queue implementation in the edmond karp algorithm
1 parent 6fed73d commit 76dd412

File tree

3 files changed

+1813
-1501
lines changed

3 files changed

+1813
-1501
lines changed

graph/edmonds_karp.ts

+38-37
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { StackQueue } from "../data_structures/queue/stack_queue";
2+
13
/**
24
* @function edmondsKarp
35
* @description Compute the maximum flow from a source node to a sink node using the Edmonds-Karp algorithm.
@@ -10,87 +12,86 @@
1012
* @return {number} - The maximum flow from the source node to the sink node.
1113
* @see https://en.wikipedia.org/wiki/Edmonds%E2%80%93Karp_algorithm
1214
*/
13-
1415
export default function edmondsKarp(
1516
graph: [number, number][][],
1617
source: number,
1718
sink: number
1819
): number {
19-
const n = graph.length
20+
const n = graph.length;
2021

2122
// Initialize residual graph
2223
const residualGraph: [number, number][][] = Array.from(
2324
{ length: n },
2425
() => []
25-
)
26+
);
2627

2728
// Build residual graph from the original graph
2829
for (let u = 0; u < n; u++) {
2930
for (const [v, cap] of graph[u]) {
3031
if (cap > 0) {
31-
residualGraph[u].push([v, cap]) // Forward edge
32-
residualGraph[v].push([u, 0]) // Reverse edge with 0 capacity
32+
residualGraph[u].push([v, cap]); // Forward edge
33+
residualGraph[v].push([u, 0]); // Reverse edge with 0 capacity
3334
}
3435
}
3536
}
3637

3738
const findAugmentingPath = (parent: (number | null)[]): number => {
38-
const visited = Array(n).fill(false)
39-
const queue: number[] = []
40-
queue.push(source)
41-
visited[source] = true
42-
parent[source] = null
39+
const visited = Array(n).fill(false);
40+
const queue = new StackQueue<number>();
41+
queue.enqueue(source);
42+
visited[source] = true;
43+
parent[source] = null;
4344

44-
while (queue.length > 0) {
45-
const u = queue.shift()!
45+
while (queue.length() > 0) {
46+
const u = queue.dequeue();
4647
for (const [v, cap] of residualGraph[u]) {
4748
if (!visited[v] && cap > 0) {
48-
parent[v] = u
49-
visited[v] = true
49+
parent[v] = u;
50+
visited[v] = true;
5051
if (v === sink) {
5152
// Return the bottleneck capacity along the path
52-
let pathFlow = Infinity
53-
let current = v
53+
let pathFlow = Infinity;
54+
let current = v;
5455
while (parent[current] !== null) {
55-
const prev = parent[current]!
56+
const prev = parent[current]!;
5657
const edgeCap = residualGraph[prev].find(
5758
([node]) => node === current
58-
)![1]
59-
pathFlow = Math.min(pathFlow, edgeCap)
60-
current = prev
59+
)![1];
60+
pathFlow = Math.min(pathFlow, edgeCap);
61+
current = prev;
6162
}
62-
return pathFlow
63+
return pathFlow;
6364
}
64-
queue.push(v)
65+
queue.enqueue(v);
6566
}
6667
}
6768
}
68-
return 0
69-
}
69+
return 0;
70+
};
7071

71-
let maxFlow = 0
72-
const parent = Array(n).fill(null)
72+
let maxFlow = 0;
73+
const parent = Array(n).fill(null);
7374

7475
while (true) {
75-
const pathFlow = findAugmentingPath(parent)
76-
if (pathFlow === 0) break // No augmenting path found
76+
const pathFlow = findAugmentingPath(parent);
77+
if (pathFlow === 0) break; // No augmenting path found
7778

7879
// Update the capacities and reverse capacities in the residual graph
79-
let v = sink
80+
let v = sink;
8081
while (parent[v] !== null) {
81-
const u = parent[v]!
82+
const u = parent[v]!;
8283
// Update capacity of the forward edge
83-
const forwardEdge = residualGraph[u].find(([node]) => node === v)!
84-
forwardEdge[1] -= pathFlow
84+
const forwardEdge = residualGraph[u].find(([node]) => node === v)!;
85+
forwardEdge[1] -= pathFlow;
8586
// Update capacity of the reverse edge
86-
const reverseEdge = residualGraph[v].find(([node]) => node === u)!
87-
reverseEdge[1] += pathFlow
87+
const reverseEdge = residualGraph[v].find(([node]) => node === u)!;
88+
reverseEdge[1] += pathFlow;
8889

89-
v = u
90+
v = u;
9091
}
9192

92-
maxFlow += pathFlow
93+
maxFlow += pathFlow;
9394
}
9495

95-
return maxFlow
96+
return maxFlow;
9697
}

0 commit comments

Comments
 (0)