Skip to content

Commit 3e532c0

Browse files
committed
feat: minimum-cost-max-flow challenge
1 parent 1338b16 commit 3e532c0

File tree

3 files changed

+82
-0
lines changed

3 files changed

+82
-0
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Challenge: Combine maximum flow and cost optimization concepts to implement an algorithm
2+
# that finds the maximum flow with the minimum cost in a network.
3+
# This is a classic combinatorial optimization challenge.
4+
# Use object-oriented programming and follow the DRY principle.
5+
6+
from min_cost_max_flow import MinCostMaxFlow
7+
8+
def main():
9+
n = 4
10+
mcmf = MinCostMaxFlow(n)
11+
mcmf.add_edge(0, 1, 3, 1)
12+
mcmf.add_edge(0, 2, 2, 2)
13+
mcmf.add_edge(1, 2, 2, 1)
14+
mcmf.add_edge(1, 3, 2, 3)
15+
mcmf.add_edge(2, 3, 3, 1)
16+
17+
flow, cost = mcmf.min_cost_max_flow(0, 3)
18+
print(f"Maximum flow: {flow}")
19+
print(f"Minimum cost: {cost}")
20+
21+
if __name__ == "__main__":
22+
main()
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
from collections import deque
2+
from typing import List, Tuple
3+
4+
class MinCostMaxFlow:
5+
def __init__(self, n: int):
6+
self.n = n
7+
self.graph = [[] for _ in range(n)]
8+
9+
def add_edge(self, u: int, v: int, capacity: int, cost: int):
10+
self.graph[u].append([v, capacity, cost, len(self.graph[v])])
11+
self.graph[v].append([u, 0, -cost, len(self.graph[u]) - 1])
12+
13+
def bellman_ford(self, source: int, dist: List[int], parent: List[Tuple[int, int]]):
14+
dist[:] = [float('inf')] * self.n
15+
dist[source] = 0
16+
in_queue = [False] * self.n
17+
queue = deque([source])
18+
in_queue[source] = True
19+
20+
while queue:
21+
u = queue.popleft()
22+
in_queue[u] = False
23+
for i, (v, capacity, cost, rev) in enumerate(self.graph[u]):
24+
if capacity > 0 and dist[u] + cost < dist[v]:
25+
dist[v] = dist[u] + cost
26+
parent[v] = (u, i)
27+
if not in_queue[v]:
28+
queue.append(v)
29+
in_queue[v] = True
30+
31+
def min_cost_max_flow(self, source: int, sink: int) -> Tuple[int, int]:
32+
flow = 0
33+
cost = 0
34+
dist = [0] * self.n
35+
parent = [(-1, -1)] * self.n
36+
37+
while True:
38+
self.bellman_ford(source, dist, parent)
39+
if dist[sink] == float('inf'):
40+
break
41+
42+
path_flow = float('inf')
43+
v = sink
44+
while v != source:
45+
u, i = parent[v]
46+
path_flow = min(path_flow, self.graph[u][i][1])
47+
v = u
48+
49+
flow += path_flow
50+
cost += path_flow * dist[sink]
51+
52+
v = sink
53+
while v != source:
54+
u, i = parent[v]
55+
self.graph[u][i][1] -= path_flow
56+
rev = self.graph[u][i][3]
57+
self.graph[v][rev][1] += path_flow
58+
v = u
59+
60+
return flow, cost

0 commit comments

Comments
 (0)