【小算法】二分图匹配之匈牙利算法详解(图例说明,代码亲测可用)

在软件开发领域,任务指派和数据关联是一种常见业务需求,比如买卖订单的匹配,共享出行的人车匹配,及自动驾驶领域中目标追踪。

我们感性的认为目标之间的匹配好像一目了然的样子,但是计算机可不这样认为。计算机是理性的,如果要处理问题,一般我们会用数据结构来表示数据,栈、队列、树、图都很常用。

不过,这是一种特殊的图,叫做二分图

二分图图最大的特点就是,图中的顶点可以分别划分到两个 Set 当中,每个 Set 中的顶点,相互之间没有边连接。

上图 a 中的红线可以是一个集合,而 b 不是。

最大匹配

按照定义,我们很容易知道,一个图中可以有许多匹配,而包含边数最多的那个匹配,我们称之为最大匹配。

完美匹配

如果一个匹配,它包含了图中所有的顶点,那么它就是完美匹配。

完备匹配

完备匹配的条件没有完美匹配那么严苛,它要求一个匹配中包含二分图中某个集合的全部顶点。比如,X 集合中的顶点都有匹配边。

匈牙利算法就是要找出一个图的最大匹配。

算法思想

其实匈牙利算法如果要感性理解起来是很容易的,核心就在于

冲突和协调

我们看看下图:

第 4 步

需要注意的是,这条路径是从顶点 C 出发的,发生了 2 次冲突,协调了两次,最终协调成功。

如果协调不成功的话,CE 这条路就不成功,它需要走另外的边,但是上图中 C 只和 E 有可能匹配,所以,如果协调不成功,C 将找不到匹配。

第 6 步

到这里,就可以了,匈牙利算法的思想和代码编写我们都掌握了。

但是,文章最后,我还是想用更学术的方式去描述和编写这个算法。

用学术的目的是让我们显得更科班,不能总是野路子凭灵感去弄是吧/p>

学术化的目的是为了让我们的思维更严谨,夯实我们的技术基础,这样遇到新的问题时,我们能够泛化解决它。

交替路与增广路

我们现在站在结果处回溯。

上面求得匈牙利的匹配结果如下图:

红实线表示两顶点匹配,灰色的虚线表示未匹配。

上面的路径中匹配的边和未匹配的边交替出现。

所以,我们的目标是去构建这样一条路径。

这涉及到两个概念:交替路和增广路。

什么是交替路/h4>

从未匹配的顶点出发,依次经过未匹配的边,匹配的边,未匹配的边,这样的路径就称为交替路。

重点是未匹配的点和未匹配的边开始

什么是增广路/h4>

从未匹配的顶点出发,按照交替路的标准寻找顶点,如果途经了另外一个未匹配的点,那么这条路径就是增广路。

增广路有一些重要的特征:

  1. 增广路中为匹配的边的数量要比匹配的边的数量多 1 条。
  2. 增广路取反(匹配的边变成未匹配,未匹配的边变成匹配)后,匹配的边的数量会加 1,从而达到匹配增广的目的。

而匈牙利算法其实就是就可以看做是一个不断寻找增广路的过程,直到找不到更多的增广路

下面图例说明:

也许有同学会问,怎么没有看见对增广路取反/p>

其实,match_list 数组就保存了匹配关系,当改变其中的值顶点的匹配关系就变了,并不需要用一个真正的链表来表示增广路。

文章知识点与官方知识档案匹配,可进一步学习相关知识

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2019年9月8日
下一篇 2019年9月8日

相关推荐