二分图最大匹配:匈牙利算法的python实现
二分图匹配是很常见的算法问题,一般用匈牙利算法解决二分图最大匹配问题,但是目前网上绝大多数都是C/C++实现版本,没有python版本,于是就用python实现了一下深度优先的匈牙利算法,本文使用的是递归的方式以便于理解,然而迭代的方式会更好,各位可以自行实现。
1、二分图、最大匹配
什么是二分图:二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。

什么是匹配:把上图想象成3位工人和4种工作,连线代表工人愿意从事某项工作,但最终1个工人只能做一种工作,最终的配对结果连线就是一个匹配。匹配可以是空。
什么是最大匹配:在愿意从事的基础上,能够最多配成几对。
现在要用匈牙利算法找出最多能发展几对。
[color=green][size=medium]
匈牙利算法是解决寻找二分图最大匹配的。
更多二分图最大匹配的图解可以参考 http://xuxueliang.blog.51cto.com/5576502/1297344
以下是代码,为了图省事使用了类,实际上并不需要这样
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()
结果为4,是正确的。各位也可以使用其它二分图来测试。
---------------------------------------------------------补充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()
结果为4,正确
二分图最大匹配:匈牙利算法的python实现的更多相关文章
- UESTC 919 SOUND OF DESTINY --二分图最大匹配+匈牙利算法
二分图最大匹配的匈牙利算法模板题. 由题目易知,需求二分图的最大匹配数,采取匈牙利算法,并采用邻接表来存储边,用邻接矩阵会超时,因为邻接表复杂度O(nm),而邻接矩阵最坏情况下复杂度可达O(n^3). ...
- Ural1109_Conference(二分图最大匹配/匈牙利算法/网络最大流)
解题报告 二分图第一题. 题目描写叙述: 为了參加即将召开的会议,A国派出M位代表,B国派出N位代表,(N,M<=1000) 会议召开前,选出K队代表,每对代表必须一个是A国的,一个是B国的; ...
- HDU 1045 - Fire Net - [DFS][二分图最大匹配][匈牙利算法模板][最大流求二分图最大匹配]
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1045 Time Limit: 2000/1000 MS (Java/Others) Mem ...
- HDU1068 (二分图最大匹配匈牙利算法)
Girls and Boys Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- poj - 3041 Asteroids (二分图最大匹配+匈牙利算法)
http://poj.org/problem?id=3041 在n*n的网格中有K颗小行星,小行星i的位置是(Ri,Ci),现在有一个强有力的武器能够用一发光速将一整行或一整列的小行星轰为灰烬,想要利 ...
- 二分图最大匹配(匈牙利算法) POJ 3041 Asteroids
题目传送门 /* 题意:每次能消灭一行或一列的障碍物,要求最少的次数. 匈牙利算法:把行和列看做两个集合,当有障碍物连接时连一条边,问题转换为最小点覆盖数==二分图最大匹配数 趣味入门:http:// ...
- HDU - 1045 Fire Net (二分图最大匹配-匈牙利算法)
(点击此处查看原题) 匈牙利算法简介 个人认为这个算法是一种贪心+暴力的算法,对于二分图的两部X和Y,记x为X部一点,y为Y部一点,我们枚举X的每个点x,如果Y部存在匹配的点y并且y没有被其他的x匹配 ...
- 51Nod 2006 飞行员配对(二分图最大匹配)-匈牙利算法
2006 飞行员配对(二分图最大匹配) 题目来源: 网络流24题 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 第二次世界大战时期,英国皇家空军从沦陷国 ...
- poj 3894 System Engineer (二分图最大匹配--匈牙利算法)
System Engineer Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 507 Accepted: 217 Des ...
- POJ1274:The Perfect Stall(二分图最大匹配 匈牙利算法)
The Perfect Stall Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 17895 Accepted: 814 ...
随机推荐
- SDP
SDP语法 一个SDP描述含有会话级信息和媒体级信息.会话级信息应用于整个会话.例如:它能成为会话始发者或者会话的名字.媒体级信息作用于特殊的媒体流.例如:它能作为一个编码器给音频流编码或者是给视频流 ...
- JavaScript 之 HelloWorld编写
HelloWorld.html 代码如下: <html><body><script type="text/javascript">documen ...
- 怎么调试nodejs restful API 以及API的Authorization
最近Nodejs,python越来越火了,同时也越来越多的人在用node写服务,可是怎么去调试服务呢?以及当你一个服务发布出去,怎么保证其安全性呢? 环境:linux unbuntu 语言:nodej ...
- 微信小程序多宫格抽奖
最近闲来无事,做了一个多宫格抽奖的例子,有什么需要改进或者错误的地方,请留言,谢谢 首先看效果 思路是先让其转动2圈多,然后再进行抽奖,格子运动用的是setTimeout,让其运行的时间间隔不一样,然 ...
- rsync随机启动脚本
服务端 #!/bin/sh # chkconfig: # description: Saves and restores system entropy pool for \ #create by xi ...
- 使用Linux环境变量
bash shell用一个叫做环境变量的特性来存储有关shell会话和工作环境的信息. 全局环境变量 这对shell 会话和所有生成的子shell都是可见的.局部变量只对创建他们的shell可见. 系 ...
- RxSwift 系列(四) -- Transforming Operators
前言 本篇文章将要学习RxSwift中四种转换操作符: map flatMap flatMapLatest scan map 通过使用一个闭包函数将原来的Observable序列转换为一个新的Obse ...
- Python爬取百度贴吧数据
本渣除了工作外,在生活上还是有些爱好,有些东西,一旦染上,就无法自拔,无法上岸,从此走上一条不归路.花鸟鱼虫便是我坚持了数十年的爱好. 本渣还是需要上班,才能支持我的业余爱好.上班时间还是尽量访问外网 ...
- 走进安卓的重灾区----video
html5的video已经出来很久了.在ios上使用基本上没什么毛病,但是安卓下就是一个重灾区了,各种体验差.这几天搞了安卓的兼容,简直是要吐血.所以特意总结了一些强势的坑点. 先看一下常用的一些属性 ...
- mysql浅龟定
一,尽量不字啊数据库做运算 1,尽量不再数据库做运算, 2,将复杂运算移动到cpu 3,尽可能简单应用mysql 二,控制表数据量 1,纯 int不超过1000w 2,含char不超过500w 3,建 ...