-
Notifications
You must be signed in to change notification settings - Fork 0
/
bipartite_graph.py
105 lines (98 loc) · 3.59 KB
/
bipartite_graph.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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/python
# coding: utf-8
from collections import deque
#==============================================================================
# Hungarian Algorithm, find maximum matching
#==============================================================================
class HungarianAlgorithm(object):
def __init__(self,graph):
"""
@graph:图的矩阵表示
"""
self.graph=graph
self.n=len(graph)
def find(self,x):
for i in range(self.n):
if self.graph[x][i]==1 and not self.used[i]:
self.used[i]=1#放入交替路
if self.match[i]==-1 or self.find(self.match[i])==1:
self.match[i]=x
self.match[x]=i
print(x+1,'->',i+1)
return 1
return 0
def hungarian_dfs(self):
"""递归形式, Depth First Search
"""
self.match = [-1] * self.n # 记录匹配情况 (current matching records)
self.used = [False] * self.n # 记录是否访问过 (visited)
m = 0
for i in range(self.n):
if self.match[i] == -1:
self.used = [False] * self.n
# print('Matching:', i)
m += self.find(i)
return m
def hungarian2(self):
"""循环形式, Breadth First Search
"""
match = [-1] * self.n#记录匹配情况
used = [-1] * self.n#记录是否访问过
Q = deque() #设置队列
ans = 0
prev = [0] * self.n #代表上一节点
for i in range(self.n):
if match[i]==-1:
Q.clear()
Q.append(i)
prev[i] = -1 #设i为出发点
flag = False #未找到增广路
while len(Q) > 0 and not flag:
u = Q.popleft()
for j in range(self.n):
if not flag and self.graph[u][j]==1 and used[j]!=i:
used[j]=i
if match[j]!=-1:
Q.append(match[j])
prev[match[j]]=u#记录点的顺序
else:
flag=True
d=u
e=j
while(d!=-1):#将原匹配的边去掉加入原来不在匹配中的边
t=match[d]
match[d]=e
match[e]=d
d=prev[d]
e=t
# print('mathch:',match)
# print('prev:',prev)
# print('deque',Q)
if match[i]!=-1:#新增匹配边
ans+=1
return ans
if __name__ == '__main__':
def do1():
graph=[(0,0,0,0,1,0,1,0),
(0,0,0,0,1,0,0,0),
(0,0,0,0,1,1,0,0),
(0,0,0,0,0,0,1,1),
(1,1,1,0,0,0,0,0),
(0,0,1,0,0,0,0,0),
(1,0,0,1,0,0,0,0),
(0,0,0,1,0,0,0,0)]
h=HungarianAlgorithm(graph)
print (h.hungarian1())
def do2():
graph=[(0,0,0,0,1,0,1,0),
(0,0,0,0,1,0,0,0),
(0,0,0,0,1,1,0,0),
(0,0,0,0,0,0,1,1),
(1,1,1,0,0,0,0,0),
(0,0,1,0,0,0,0,0),
(1,0,0,1,0,0,0,0),
(0,0,0,1,0,0,0,0)]
h=HungarianAlgorithm(graph)
print (h.hungarian2())
do1()
do2()