# 二分图最大匹配：匈牙利算法的python实现

1、二分图、最大匹配

[color=green][size=medium]

M=[]
class DFS_hungary():

def __init__(self, nx, ny, edge, cx, cy, visited):
self.nx, self.ny=nx, ny
self.edge = edge
self.cx, self.cy=cx,cy
self.visited=visited

def max_match(self):
res=0
for i in self.nx:
if self.cx[i]==-1:
for key in self.ny:         # 将visited置0表示未访问过
self.visited[key]=0
res+=self.path(i)return res

def path(self, u):
for v in self.ny:
if self.edge[u][v] and (not self.visited[v]):
self.visited[v]=1
if self.cy[v]==-1:
self.cx[u] = v
self.cy[v] = u
M.append((u,v))
return 1
else:
M.remove((self.cy[v], v))
if self.path(self.cy[v]):
self.cx[u] = v
self.cy[v] = u
M.append((u, v))
return 1
return 0

ok，接着测试一下：

if __name__ == '__main__':
nx, ny = ['A', 'B', 'C', 'D'], ['E', 'F', 'G', 'H']
edge = {'A':{'E': 1, 'F': 0, 'G': 1, 'H':0}, 'B':{'E': 0, 'F': 1, 'G': 0, 'H':1}, 'C':{'E': 1, 'F': 0, 'G': 0, 'H':1}, 'D':{'E': 0, 'F': 0, 'G': 1, 'H':0}} # 1 表示可以匹配， 0 表示不能匹配
cx, cy = {'A':-1,'B':-1,'C':-1,'D':-1}, {'E':-1,'F':-1,'G':-1,'H':-1}
visited = {'E': 0, 'F': 0, 'G': 0,'H':0}

print DFS_hungary(nx, ny, edge, cx, cy, visited).max_match()

---------------------------------------------------------补充BFS版本匈牙利算法-------------------------------------------------------

BFS版本的匈牙利算法性能更好一些，但是比较难理解，下面把BFS版本的算法也贴出来，也是翻译自c++版本，这次使用更好的迭代方式替换了递归方式

def BFS_hungary(g,Nx,Ny,Mx,My,chk,Q,prev):
res=0
for i in xrange(Nx):
if Mx[i]==-1:
qs=qe=0
Q[qe]=i
qe+=1
prev[i]=-1

flag=0
while(qs<qe and not flag):
u=Q[qs]
for v in xrange(Ny):
if flag:continue
if g[u][v] and chk[v]!=i:
chk[v]=i
Q[qe]=My[v]
qe+=1
if My[v]>=0:
prev[My[v]]=u
else:
flag=1
d,e=u,v
while d!=-1:
t=Mx[d]
Mx[d]=e
My[e]=d
d=prev[d]
e=t
qs+=1
if Mx[i]!=-1:
res+=1
return res

if __name__ == '__main__':
g=[[1,0,1,0],[0,1,0,1],[1,0,0,1],[0,0,1,0]]
Nx=4
Ny=4
Mx=[-1,-1,-1,-1]
My=[-1,-1,-1,-1]
chk=[-1,-1,-1,-1]
Q=[0 for i in range(100)]　　　　prev=[0,0,0,0]        print BFS_hungary()

posted @ 2016-06-11 15:31  JamesPei  阅读(10997)  评论(2编辑  收藏  举报