二分图带权匹配(推箱子问题的思考)

博客搬家:最爱午后红茶

转载请附上原文链接: http://blog.csdn.net/u013351484/article/details/51598270

二分图带权匹配(也叫二分图最优(最佳)匹配,Kuhn-Munkres 算法

预备知识:二分图最大匹配,二分图完备(完美)匹配

源码以及展示地址: https://github.com/QYPan/sokoban4

二分图带权匹配,可以把它看作集合 X 的每个顶点到集合 Y 的每个顶点均有边的二分图(设权重均为正数,则原来分别在集合 X 与集合 Y 中没边的顶点 xi,yi 就可以添加一条权重为 0 的边,即 w[xi,yi] = 0);这样的二分图必定存在完备匹配。

接下来求解二分图最大权值匹配过程的所有内容都将以下面这个例子展开:

设有二分图 G:

最好把这个表画在纸上 :)

首先要有顶标的概念:

二分图最大权值匹配通过给集合 X 和集合 Y 的每个顶点定义一个值,称为顶标;可以设集合 X 里的顶点 xi 的顶标为 lx[i],集合 Y 同理。算法执行过程中确保 lx[i] + ly[j] >= w[xi, yj] 成立(只有这式子成立,才能证明 km 算法的正确性)。

图 G 在算法刚开始执行时要满足 lx[i] + ly[j] >= w[xi, yj] 的要求可以这样设定:lx[i] 等于 xi 与集合 Y 中所有顶点连线的最大值;即 lx[i] = max{w[xi, yj]},j = {0, ... , 4},ly[i] 全为 0;因此,一开始的图可以是这样:

接着要有相等子图的概念:

二分图中满足 lx[i] + ly[j] = w[xi,yj] 的边称为等边,而由等边构成的子图称为相等子图。如上图就是一个相等子图;上图去掉任意边(至少保留一条)仍为相等子图;但上图增加任意边就不是相等子图了,因为增加任意边都会使得新增加的边的 lx[i] + ly[j] > w[xi, yj]。

接着就会有:

如果二分图的相等子图存在完备匹配,那这个完备匹配就是二分图的最大权值匹配。因为对于二分图的任意一个匹配,如果它包含于相等子图,那么它的边权和等于所有顶点的顶标和;如果它有的边不包含于相等子图,那么它的边权和小于所有顶点的顶标和。所以相等子图的完备匹配一定是二分图的最大权匹配。看不懂没关系,把整个过程搞一遍再回来看看也许就理解了。

因此,二分图最大权值匹配的过程其实就是通过修改集合 X 与集合 Y 的顶标使得二分图里 lx[i] + ly[j] = w[xi, yi] 的边不断增多,也即相等子图不断扩大,直到相等子图出现完备匹配为止;而此完备匹配就是所求。

km 算法流程基本基于下图:

再接着就会有:怎样修改顶标?什么情况下要修改顶标?带着这个疑问往下走~

有了以上的概念(虽然可能还是模模糊糊),我们尝试找出二分图 G 的最大权值匹配。

为了理解方便,求解过程都是基于 DFS 的顺序。

那~,开始了:

1)

为 X0 找交错路,X0 -> Y1;这一步是没有问题的。

2)

为 X1 找交错路,X1 -> Y1 -> X0;终点不在

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值