本文介绍图论中的匈牙利算法以及KM算法,适用于二部图最大权匹配问题。
二部图
二部图,也称为偶图。偶图是指具有二分类(X,Y)的图,它的点集可以分解为两个(非空)子集X和Y,使得每条边的一个端点在X中, 另一个端点在Y中。
完全偶图就是X中每一个点与Y中每一个点都有连边。
下图就是一个二部图,但不是完全偶图
匹配
给定
,则匹配
, 且
中任意的两条边不相邻。
中一条边的两个端点称为在
下是配对的,同时这两个点也是
饱和的。若在
下,
的每一个顶点都是饱和的, 则称M为G的
完美匹配。若
没有另外的匹配
,使得
,则称为
的
最大匹配。
完美匹配也是
最大匹配, 反之不成立。
二部图都有最大匹配,但是只有在
时才可能有完美匹配。
与
点数相等的
完全偶图显然一定有完美匹配。
对于一个
的
完全偶图,如果每一条边都有一个权重,那么在其中寻找一个具有最大权和的完美匹配,就称这个匹配为
最优匹配。
匈牙利算法
匈牙利算法可以用于在偶图中寻找最大匹配。
算法如下:
给定图
利用匈牙利算法寻找最大匹配,首先对于
按照顺序一个个匹配相应的
step1中:
-
匹配到
-
尝试匹配失败,则开始匹配成功
-
尝试匹配失败,则开始匹配成功
step2中:
尝试匹配
都失败,而又无其它相连顶点。此时
匈牙利算法开始起到作用,它的思路很简单,当端点无法匹配的时候,我们尝试找一条
增广路。
增广路定义如下:增广路的起点与终点均为非饱和点的交错路。交错路就是处于匹配中的边和未处于匹配中的边相互交错组成的路。
对于一条增广路,将黄色红色相互交换,相当于匹配边与未匹配边相互交换,这样增广路上所有的点就变成了饱和点,且匹配的边增加1。
如上图,我们对于
利用DFS找到了一条增广路,然后根据其进行扩充如下
同时对于
自然的扩展到
则找到了最大匹配。
综上,匈牙利算法如下:
- 初始化顶点编号,令n=1。
- 若n大于顶点数N,结束。否则步骤3。
- 深度优先搜索寻找顶点n的可扩路。如果找到,进行扩充,如果未找到,则这个顶点没法饱和。n = n + 1,返回步骤2。
代码如下:
// n = x.size(), m = y.size()
匈牙利算法的思想很简单,对于每个
中的点
进行匹配,或者
可以直接匹配
中的点
,即(y_match[i]=-1),或者点
原本对应的
中的点 y_match[i] 可以找到另外一条路径。即增广路。