-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdinic.py
85 lines (77 loc) · 2.93 KB
/
dinic.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import numpy as np
from collections import defaultdict
#Dinic Algorithm
class Dinic():
def __init__(self) -> None:
self.cnt = 0
self.str2int = {}
self.adjacent_table = {}
self.forward_matrix = None
# self.edge = {}
def add(self, vertices):
for vertex in vertices:
new_d = {}
new_d[self.cnt] = defaultdict(int)
self.adjacent_table.update(new_d)
self.str2int[vertex] = self.cnt
self.cnt += 1
def add_edge(self, source, terminal, capacity):
# self.edge.append((source, terminal, capacity))
neighbor_dict = self.adjacent_table[self.str2int[source]]
neighbor_dict[self.str2int[terminal]] = capacity
def construct_table(self):
num = len(self.str2int)
self.adjacent_table = np.zeros((num, num), dtype=np.int32)
for s, t, c in self.edge:
ss, tt = self.str2int[s], self.str2int[t]
self.adjacent_table[ss, tt] = c
def calc_max_flow(self, source, terminal):
# if not self.adjacent_table:
# self.construct_table()
self.max_flow = self._calc_max_flow(self.adjacent_table, self.str2int[source], self.str2int[terminal])
def bfs(self, C, F, s, t):
n = len(C)
queue = []
queue.append(s)
global level
level = n * [0] # initialization
level[s] = 1
while queue:
k = queue.pop(0)
# for i, cap in F[k].items():
# if (F[k].get(i, 0) < cap) and (level[i] == 0): # not visited
# level[i] = level[k] + 1
# queue.append(i)
for i in range(n):
if (F[k][i] < C[k][i]) and (level[i] == 0): # not visited
level[i] = level[k] + 1
queue.append(i)
return level[t] > 0
def dfs(self, C, F, k, cp):
tmp = cp
if k == len(C)-1:
return cp
for i in range(len(C)):
if (level[i] == level[k] + 1) and (F[k][i] < C[k][i]):
f = self.dfs(C,F,i,min(tmp,C[k][i] - F[k][i]))
F[k][i] = F[k][i] + f
F[i][k] = F[i][k] - f
tmp = tmp - f
# for i in range(len(C)):
# if (level[i] == level[k] + 1) and (F[k][i] < C[k][i]):
# f = Dfs(C,F,i,min(tmp,C[k][i] - F[k][i]))
# F[k][i] = F[k][i] + f
# F[i][k] = F[i][k] - f
# tmp = tmp - f
return cp - tmp
def _calc_max_flow(self, C, s, t):
F = np.zeros((self.cnt, self.cnt), dtype=np.int32)
# F = defaultdict(defaultdict(int))
flow = 0
while(self.bfs(C,F,s,t)):
flow = flow + self.dfs(C,F,s,100000)
self.forward_matrix = F
return flow
def get_flow(self, source, terminal):
s, t = self.str2int[source], self.str2int[terminal]
return self.forward_matrix[s][t]