python dfs算法_匈牙利&KM算法

本文介绍图论中的匈牙利算法以及KM算法,适用于二部图最大权匹配问题。

二部图

二部图,也称为偶图偶图是指具有二分类(X,Y)的图,它的点集可以分解为两个(非空)子集X和Y,使得每条边的一个端点在X中, 另一个端点在Y中。

完全偶图就是X中每一个点与Y中每一个点都有连边。

下图就是一个二部图,但不是完全偶图

636f969ccb1f5617a975372ce05c49bf.png

匹配

给定

,则匹配
, 且
中任意的两条边不相邻。
中一条边的两个端点称为在
下是配对的,同时这两个点也是
饱和的。若在
下,
的每一个顶点都是饱和的, 则称M为G的
完美匹配。若
没有另外的匹配
,使得
,则称为
最大匹配完美匹配也是 最大匹配, 反之不成立。

二部图都有最大匹配,但是只有在

时才可能有完美匹配。
点数相等的
完全偶图显然一定有完美匹配。

对于一个

完全偶图,如果每一条边都有一个权重,那么在其中寻找一个具有最大权和的完美匹配,就称这个匹配为 最优匹配

匈牙利算法

匈牙利算法可以用于在偶图中寻找最大匹配

算法如下:

给定图

28cf8a014cad6fdc10ed0f542c5707b7.png
G

利用匈牙利算法寻找最大匹配,首先对于

按照顺序一个个匹配相应的

309195ecd91850ccd9d514ceb3e849ed.png
step1

step1中:

  1. 匹配到
  2. 尝试匹配
    失败,则开始匹配
    成功
  3. 尝试匹配
    失败,则开始匹配
    成功

315424b289749c1fd66083b39cf63801.png
step2

step2中:

尝试匹配
都失败,而又无其它相连顶点。此时
匈牙利算法开始起到作用,它的思路很简单,当端点无法匹配的时候,我们尝试找一条 增广路

增广路定义如下:增广路的起点与终点均为非饱和点的交错路交错路就是处于匹配中的边和未处于匹配中的边相互交错组成的路。

e8854bf86f3f1c2b7b9bc4bfad2eb2a7.png
匈牙利算法中的增广路,红色边为匹配的边,红色的点为饱和点

对于一条增广路,将黄色红色相互交换,相当于匹配边未匹配边相互交换,这样增广路上所有的点就变成了饱和点,且匹配的边增加1。

e2362cd8c22d565590b57b7df02f3c4d.png
对于X4的一条增广路

如上图,我们对于

利用DFS找到了一条增广路,然后根据其进行扩充如下

fd22f695a776e13a3315f651160247f1.png

同时对于

自然的扩展到

6b526f3a7bc0b89566be434d6f4cdc28.png

则找到了最大匹配。

综上,匈牙利算法如下:

  1. 初始化顶点编号,令n=1。
  2. 若n大于顶点数N,结束。否则步骤3。
  3. 深度优先搜索寻找顶点n的可扩路。如果找到,进行扩充,如果未找到,则这个顶点没法饱和。n = n + 1,返回步骤2。

代码如下:

// n = x.size(), m = y.size()

匈牙利算法的思想很简单,对于每个

中的点
进行匹配,或者
可以直接匹配
中的点
,即(y_match[i]=-1),或者点
原本对应的
中的点 y_match[i] 可以找到另外一条路径。即增广路。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值