您的位置:首页 > 其它

二分图最大匹配与其应用

2016-05-07 10:22 281 查看


部分定义

传递闭包

一个图。如果图GG中点ii到点jj存在通路,那么在传递闭包中有边i−>ji->j

二分图

一个图GG,可以将其所有点分成x,yx,y两个点集,同时所有边满足他的两个端点分别落在x,yx,y上,而不会落在同一个集合里。

匹配

实际为原图GG一个边集,GG中任意点作边的端点至多一次。

通俗一点的说法:将图中部分或所有点一对一对通过一条边配起来

最大匹配:边集中边数最多的一个匹配。

.

举例来说:如下图所示,如果在某一对男孩和女孩之间存在相连的边,就意味着他们彼此喜欢。是否可能让所有男孩和女孩两两配对,使得每对儿都互相喜欢呢?图论中,这就是完美匹配问题。如果换一个说法:最多有多少互相喜欢的男孩/女孩可以配对儿?这就是最大匹配问题。



增广路

在图GG与图GG的一个匹配边集MM的前提下

一条由未匹配顶点xx到yy的路径。

这条路径上一条是已匹配边,一条是未匹配边,如此相交错(交替路),

其中第一条和最后一条边一定不是匹配边 (因为x,yx,y未匹配)。

因为增广路主要应用于匈牙利算法中,用于求二分图最大匹配,所以我们一般在二分图基础上讨论他。

增广路的性质:

1 有奇数条边。

匹配边与未匹配边交替出现且首尾都为未匹配边。

2 路径上的点一定是一个在左半边,一个在右半边,交替出现。

由二分图性质得,因为二分图同一边的点之间没有边相连。

3 路径上的所有第奇数条边都不在原匹配中,所有第偶数条边都出现在原匹配中。

同上

4 增广路径的取反可扩大匹配

增广路径的取反:

把增广路径上的所有未匹配边加入到原匹配中去,并把增广路径中的所有匹配边边从原匹配中删除。

显然的这条路径上的一个点可以和他相邻的两个点匹配。

所以我们调整增广路上的端点的匹配顺序,将空出的x,yx,y匹配

这样变动依旧每个顶点只会出现一次,且边数增加了一条

二分图最大匹配_匈牙利算法

既然我们知道增广路的取反可以增加匹配边数,那我们就不断的去找增广路去取反他,直到没有为止。当找不到增广路时,那么当前匹配就是最大匹配(增广路定理),匈牙利算法正是这么做的。

一个老司机写的教程:老司机开车就是稳!

伪代码

bool find(int x){
for (与x相连且当前没有找过增广路的点i) {
标记找过;
if (i已经匹配过) {
找与i匹配的点是否有增广路,//if find(link(i)) 这里就相当于交替路了
如果是:返回true表示有增广路;
} else  {
可做增广路末端点,返回true;
}
}
return false;
}
for (i=1;i<=n;i++) //每个左边点
{
memset(used,0,sizeof(used));
if find(i) all+=1; //找增广路
}


其实理解上来说我们可以想成一个不断让的过程(贪心),其原理自己清楚就好。

时间复杂度分析

枚举每个点的增广路为n;

最坏情况枚举所有边m;

虽然最坏O(nm)的复杂度比较难看,但是匈牙利算法在实际应用中平均复杂度还是比较优秀的,且思维难度不大,代码复杂度低,是比较可取的一种二分图最大匹配算法。

其他算法有网络流,还有分层优化的匈牙利,以后再看看吧。

应用

(1)二分图的最小顶点覆盖

最小顶点覆盖要求用最少的点(X或Y中都行),让每条边都至少和其中一个点关联。

-Knoig定理:二分图的最小顶点覆盖数等于二分图的最大匹配数。

(2)有向无环图(DAG)的最小路径覆盖

用尽量少的不相交简单路径覆盖有向无环图G的所有顶点,这就是DAG图的最小路径覆盖问题。

结论:DAG图的最小路径覆盖数 = 节点数(n)- 新图最大匹配数(m)

新图为把每一个顶点x分为入点和出点x,x’两个集合,对于由x->y的边,在新图中连x’->y,这样会得到一个二分图

如何理解? 一点对在原图中意味着两个路径合并为一个。

(3)二分图的最大独立集

最大独立集问题: 在N个点的图G中选出m个点,使这m个点两两之间没有边.求m最大值

结论:二分图的最大独立集数 =节点数(n)— 最大匹配数(m)

最大独立集=最小覆盖。 这个显然。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: