二分图之匈牙利算法

来源:互联网 发布:hadoop java 编辑:程序博客网 时间:2024/04/28 02:57

二分图的基本概念就不说了,就是一个图,点可以分成两个部分,左边和右边。  左边的点只能连接到右边的点,而不能存在某些边是连接左边的两个点或连接右边的两个点。如三角形,就不是二分图。四边形就是二分图,把对角的两个点放到左边,另外的两个点放到右边,就明显是二分图了。为了下面叙述方便,左边的点集称为X,右边的称为Y。

求二分图的最大匹配有两个算法,一个是利用最大流求,一个是利用匈牙利算法。匈牙利算法比较简洁。

1、匈牙利算法

1.1 增广路径

饱和点:有匹配边连接的点。如图1中的1  5  2   6 都是饱和点,而边E(1,5),E(2,6)都是匹配边。

增广路径:从一个未饱和点开始,依次经过未匹配边、匹配边、未匹配边、未匹配边……所得的路叫做交替路。注意,如果交替路的终点是一个非饱和点,那么这条路,就叫做增广路。如图2中的3-》6-》2-》5-》1-》4就是一条增广路径。
增广路径的几条性质,非常重要。
(1)有奇数条边。
(2)起点在二分图的左半边,终点在右半边。
(3)路径上的点一定是一个在左半边,一个在右半边,交替出现。(其实二分图的性质就决定了这一点,因为二分图同一边的点之间没有边相连,不要忘记哦。)
(4)整条路径上没有重复的点。
(5)起点和终点都是目前还没有配对的点,而其它所有点都是已经配好对的。(如图1、图2所示,[1,5]和[2,6]在图1中是两对已经配好对的点;而起点3和终点4目前还没有与其它点配对。)
(6)路径上的所有第奇数条边都不在原匹配中,所有第偶数条边都出现在原匹配中。(如图1、图2所示,原有的匹配是[1,5]和[2,6],这两条配匹的边在图2给出的增广路径中分边是第2和第4条边。而增广路径的第1、3、5条边都没有出现在图1给出的匹配中。)
(7)最后,也是最重要的一条,把增广路径上的所有第奇数条边加入到原匹配中去,并把增广路径中的所有第偶数条边从原匹配中删除(这个操作称为增广路径的取反),则新的匹配数就比原匹配数增加了1个。(如图2所示,新的匹配就是所有蓝色的边,而所有红色的边则从原匹配中删除。则新的匹配数为3。)
增广路定理:
一个匹配是最大匹配的充分必要条件是  不存在增广路。

1.2 匈牙利树

理解 二分匹配,很多书或者资料上都没有提匈牙利树,但是,我觉得匈牙利树对理解匈牙利算法起很重要的作用。而且匈牙利树很简单。看下图:

从b开始搜增广路径,搜到了一个交替路径树,从C开始搜,搜到了匈牙利树。交替路径树和匈牙利树的区别是叶子节点是否是自由的(非匹配的)节点。
有一个非常重要的性质
如果在搜索增广路径的过程中,检索到一棵匈牙利树,就可以永久的把它从二分图中删除,而不影响检索。

1.3 匈牙利算法

挨着搜左边的顶点(X集合中的点),找其增广路径。有两种结果:一、找到了增广路径,则最大匹配数加一;二、找到了匈牙利树,则不理会(从图中删除树节点比较麻烦)。这样,把X集中的点搜一遍,即可找到最大二分匹配。
说明:
1、如果搜某点的时候,找到了增广路径,则这个点会进入匹配。以后不管再怎么搜,再怎么着增广路径,怎么变换匹配。这个点会一直在匹配中的。
2、如果搜某点的时候,找不到增广路径,那就一定找到了匈牙利树。那么根据上面绿色的性质,可以将其删除掉而不影响以后的搜索,即以后的搜索变换了原来的匹配后,对这个点是没有影响的,也就是说,这个点永远不会进入匹配了。
基于以上的两点,只要遍历一遍左边(X)中的点,就可以找到最大二分匹配了。因为每个点搜过后,就绝对了它们最终的结果是否出现在匹配中。而不受未来搜索的影响。

原创粉丝点击