二分匹配
如何在 C 或 C++ 中实现二分匹配算法(可能基于最大流算法)?
具体来说,我在文件中输入了以下内容: (1,3) (1,5) (2,5)
(M,F) --> 其中M代表MALE的id,F代表FEMALE的id。
我需要找到最大匹配数并显示匹配的情侣。 喜欢: 匹配: 1&3 , 2&5
我在一些书中读过,我可以将这个问题基于“网络中的最大流量”算法,但除了“这个问题可以解决”这句话之外,我找不到任何具体信息通过......算法”。 我对 max-flow 知之甚少,也不知道如何实现它......
How can I implement a bipartite matching algorithm (probably based on a max-flow algorithm) in C or C++ ?
To be specific, I have this input in a file:
(1,3)
(1,5)
(2,5)
(M,F) --> where M represents id of MALE and F is id of FEMALE.
I need to find the maximum number of matches and show matched couples.
Like:
matches: 1&3 , 2&5
I have read in some books I can base this problem on a "maximum flow in a network" algorithm, but I couldn't find any specific info other than the sentence "this problem can be solved by .... algorithm".
I have little knowledge about max-flow, and dont know how to implement it either...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
以下是最大二分匹配的流算法的实验研究:
获胜者是推送重新标记算法,我相信该算法是来自 Andrew Goldberg 的“BIM”包的实现,您可以在此处下载:
http://www.avglab.com/andrew/soft.html
请注意,如果编写代码很重要正如杰西建议的那样,您可能想选择福特-福克森。 如果您这样做,我建议您使用广度优先搜索,而不是深度优先搜索,来查找增广路径(原因在上面的文章中解释)。
Here is an experimental study of flow algorithms for maximum bipartite matching:
The winner was a push-relabel algorithm, which I believe was the implementation from Andrew Goldberg's "BIM" package, which you can download here:
http://www.avglab.com/andrew/soft.html
Mind you, if it's important that you code up the solution yourself, you might want to settle for Ford-Fulkerson, as Jesse suggested. If you do that, I recommend you use breadth-first search, not depth-first search, to find the augmenting path (for reasons explained in the article above).
QuickGraph 库包含一个二分匹配算法,我刚刚研究并检查了修复。 它封装了 Edmonds Karp 最大流算法。
到目前为止,该算法的唯一文档是我添加的单元测试。 如果有人想添加一个(希望更快的)实现,而不是简单地包装最大流算法,请与我联系。
The QuickGraph library includes a bipartite matching algorithm, which I just worked on and checked in a fix for. It wraps the Edmonds Karp maximum flow algorithm.
The only documentation for the algorithm so far is the unit tests I added. If anyone would like to add a (hopefully faster) implementation which does not simply wrap a maxflow algorithm, please contact me.
是的,如果您已经有解决最大流问题的代码,您可以使用它通过转换图形来解决二分匹配,如 这个讲座,但如果您从头开始,这可能不是正确的方法。 如果您只想实现一些相当简单的代码来解决问题,但示例不会太大,那么最好使用简单的增强路径方法,如下所示 此处。 这为您提供了一种 O(|V||E|) 方法,该方法非常容易编码,并且适用于除非常大的图形之外的所有图形。 如果您想要具有更好的最坏情况性能的东西,您可以尝试 Hopcraft-Karp 算法,它一次找到多个增广路径,并且具有 O(sqrt(|V|)|E|) 运行时间限制,但维基百科上的文章指出:
无论如何,在尝试解决 Hopcraft-Karp 或维基百科文章参考文献中提到的推送相关技术之一之前,您绝对应该理解并能够实现简单的增强路径方法。
编辑:由于某种原因,上面的链接没有正确显示。 以下是有问题的网址:(http://oucsace.cs .ohiou.edu/~razvan/courses/cs404/lecture21.pdf), (http://www.maths.lse.ac.uk/Courses/MA314/matching.pdf),以及(http://en.wikipedia.org/wiki/Hopcroft–Karp_algorithm)。
Yes, if you already have code to solve the max-flow problem, you can use it to solve bipartite matching by transforming the graph as shown towards the end of this lecture, but that's probably not the right approach if you are starting from scratch. If you just want to implement some fairly simple code to solve the problem for examples that don't get too huge, you are better off using a simple augmenting path approach as outlined here. That gives you an O(|V||E|) approach that is pretty easy to code and adequate for all but very large graphs. If you want something with better worst-case performance, you could try the Hopcraft-Karp algorithm, which finds multiple augmenting paths at once and has a O(sqrt(|V|)|E|) run time bound, but the Wikipedia article on it notes that:
In any case, you should definitely understand and be able to implement a simple augmenting-path approach before trying to tackle either Hopcraft-Karp or one of the push-relable techniques mentioned in the references of the Wikipedia article.
Edit: For some reason, the links above aren't showing up correctly. Here are the URLs in question: (http://oucsace.cs.ohiou.edu/~razvan/courses/cs404/lecture21.pdf), (http://www.maths.lse.ac.uk/Courses/MA314/matching.pdf), and (http://en.wikipedia.org/wiki/Hopcroft–Karp_algorithm).
是的,二分匹配可以减少到最大流量:
您将获得一组节点
M
和F
。 如果您已经获得了从M
中的节点m
到F
中的节点f
的有向边,请添加一条有向边在您的文件中配对(m, f)
。添加一个节点
S
,其有向边从S
到M
中的每个节点(这是您的“超级源”节点)。添加一个节点
T
,该节点具有从F
中的每个节点到T
的有向边(这是您的“超级接收器”节点) )。现在,您需要找到从
S
到T
的最大流量(所有边的权重均为 1)。那么最大流量到底是多少呢? 从
S
到T
的流是一组边,使得对于每个节点(S
和>T
),其流入边的权重与其流出边的权重相同。 想象一下,您的图表是一系列管道,您将水从S
处倒入系统,并在T
处放出。 在其间的每个节点,流入的水量必须与流出的水量相同。尝试让自己相信一个流程对应于您的原始集合的匹配。 (给定一个流量,如何获得匹配?给定一个匹配,如何获得流量?)
最后,要找到图中的最大流量,可以使用 福特-Fulkerson 算法。 上面的维基百科页面用伪代码对其进行了很好的描述。
Yes, bipartite matching can be reduced to maximum flow:
You're given sets of nodes
M
andF
. Add a directed edge from a nodem
inM
to a nodef
inF
if you've got the pair(m, f)
in your file.Add a single node
S
with a directed edge fromS
to every node inM
(this is your "super-source" node).Add a single node
T
with a directed edge from every node inF
toT
(this is your "super-sink" node).Now, you need to find the maximum flow (with all your edges of weight 1) from
S
toT
.So what the heck is maximum flow? A flow from
S
toT
is a set of edges such that for each node (exceptS
andT
), the weight of its in-flux edges is the same as the weight of its out-flux edges. Imagine that your graph is a series of pipes, and you're pouring water in the system atS
and letting it out atT
. At every node in between, the amount of water going in has to be the same as the amount of water coming out.Try to convince yourself that a flow corresponds to a matching of your original sets. (Given a flow, how to you get a matching? Given a matching, how to you get a flow?)
Finally, to find the maximum flow in a graph, you can use the Ford-Fulkerson algorithm. The above wikipedia page gives a good description of it, with pseudo-code.