二分图中的最大匹配

时间:2011-08-29 16:07:01

标签: c algorithm matching bipartite network-flow

我遇到了二分图问题中的最大匹配问题。问题是这样的:

给出一个带有圆形孔的板并给出一组n个圆盘。孔的编号为h 1 ,...,h m ,圆盘编号为d 1 ,...,d n

我们有一个m行和n列的矩阵A. A [i] [j] = 1,如果h i 可以拟合d j (即h i ≥直径d > j ),否则为0。

鉴于任何一个孔最多只能包含一个光盘的情况,我需要找到最大孔的配置。

我已经读过这个问题可以建模到网络流量问题,但不能完全遵循如何。有人可以解释如何做到这一点?另外,有没有我可以看到的C代码?

1 个答案:

答案 0 :(得分:5)

从二分匹配到最大流量的减少实际上非常漂亮。当您获得二分图时,您可以将图形视为由第一列到第二列的边连接的两列节点:

  A ----- 1
  B --\   2
  C    \- 3
 ...     ...
  Z       n

要将问题减少到max-flow,首先要将所有边从第一列引导到第二列,以便流只能从左列移动到右边。执行此操作后,您将引入两个新节点s和t作为源节点和终端节点。定位s使其连接到左侧的所有节点和t,以便右侧的每个节点都连接到它。例如:

     A ----- 1
 /   B --\   2   \
s-   C    \- 3   - t
 \  ...     ...  /
     Z       n

这里的想法是,你可以从s到t的任何路径必须输入左列中的一个节点,然后将一些边缘交叉到右边的列,然后从那里到t。因此,匹配路径和st路径中的边缘有一个简单的一对一映射:只需从s到路径的源路径,然后沿着边缘,然后沿着从端点到节点的边缘吨。此时,我们的目标是找到最大化从s到t的节点不相交路径数量的方法。我们可以使用如下的最大流量来实现这一点。首先,将每个边缘的容量设置为s,这样可以确保最多一个流量单位进入第一列中的每个节点。类似地,将穿过两列的每条边的容量设置为1,确保我们选择边缘或不选择边缘,而不是可能选择具有多重性的边缘。最后,将离开第二列的边的容量设置为t也是一。这确保了右侧的每个节点只匹配一次,因为我们不能通过它推动多个流量单位。

构建流网络后,使用任何标准算法计算最大流量。 Ford-Fulkerson 是一种在此处运行良好的简单算法,因为图中的最大流量等于节点数。它的最差情况是O(mn)。或者,高度优化的 Hopcroft-Karp algorithm 可以在O(m√n)时间内完成此操作,这可能会更好。

对于C实施,快速Google搜索Ford-Fulkerson步骤出现 this link 。在将流程网络传递给此代码之前,您需要构建流程网络,但构造并不复杂,我认为您不应该遇到太多麻烦。

希望这有帮助!