最近的研究需要,学习二部图的匹配问题,自然就学习了匈牙利算法,虽然跟我目前要解决的问题--多对多加权双边匹配问题有许多不同,但算是二部图匹配的入门算法。
在网上看到不错的博文,借来学习。
http://blog.youkuaiyun.com/pi9nc/article/details/11848327
该博文基本概念讲得不错
匈牙利算法(二部图匹配、已知各个节点的偏好集合、无权匹配、一对一、最大化所有匹配边数)
二部图G=(V, E)最大匹配问题。V = V1 U V2,顶点集V可以分割为两个互不相交的子集就V1和V2.
其中任意两条边都没有公共顶点.
在图论中,一个「匹配」(matching)是一个边的集合,其中任意两条边都没有公共顶点。这样的子集中边数最大的子集称为图的最大匹配问题.
一个图所有匹配中,所含匹配边数最多的匹配,称为这个图的最大匹配。
--------【从定义上来看,传统的匈牙利算法不能用来解决多对多匹配问题,只能解决一对一匹配,且目标为匹配数最大,不是权值】
该算法的核心就是寻找增广路径。研究增广路的意义是改进匹配。只要把增广路中的匹配边和非匹配边的身份交换即可。由于中间的匹配节点不存在其他相连的匹配边,所以这样做不会破坏匹配的性质。交换后,图中的匹配边数目比原来多了 1 条。我们可以通过不停地找增广路来增加匹配中的匹配边和匹配点。找不到增广路时,达到最大匹配。
1.从左边第 1 个顶点开始,挑选未匹配点进行搜索,寻找增广路。
1)如果经过一个未匹配点,说明寻找成功。更新路径信息,匹配边数 +1,停止搜索。
2)如果一直没有找到增广路,则不再从这个点开始搜索。事实上,此时搜索后会形成一棵匈牙利树。我们可以永久性地把它从图中删去,而不影响结果。
2.由于找到增广路之后需要沿着路径更新匹配,所以我们需要一个结构来记录路径上的点。DFS 版本通过函数调用隐式地使用一个栈,而 BFS 版本使用 prev 数组。
http://www.matrix67.com/blog/archives/39
该博文中的总结:【讲得还不错】
从二分图中找出一条路径来,让路径的起点和终点都是还没有匹配过的点,并且路径经过的连线是一条没被匹配、一条已经匹配过,再下一条又没匹配这样交替地出现。找到这样的路径后,显然路径里没被匹配的连线比已经匹配了的连线多一条,于是修改匹配图,把路径里所有匹配过的连线去掉匹配关系,把没有匹配的连线变成匹配的,这样匹配数就比原来多1个。不断执行上述操作,直到找不到这样的路径为止。
http://blog.youkuaiyun.com/dark_scope/article/details/8880547
该博文讲的比较生动易懂。按顺序一个一个匹配,后面的找不到“回溯”、“腾”地方。
有机会上,没机会创造机会也要上。
找妹子是个递归的过程,最最关键的字就是“腾”字。
http://www.cnblogs.com/kuangbin/archive/2012/08/19/2646535.html
二部图最大权匹配,KM算法