当前位置: 首页 > news >正文

运筹学之指派问题(原始匈牙利算法以及KM算法)

1.图论概念review

1.1 无向完全图

无向完全图 : ‌完全图是一个无向图‌,其中 ‌每一对不同的顶点之间都恰好有一条边直接相连‌。即,若图有 n 个顶点,则任意两个顶点间均存在唯一的一条边‌。边数是 n ( n − 1 ) / 2 n(n-1)/2 n(n1)/2 .

1.2 完全二分图

完全二分图 :其顶点集 V被严格划分为两个互不相交的子集 X 和 Y,且 ‌X 中的每个顶点与 Y 中的每个顶点均有且仅有一条边相连‌,但 X 或 Y内部的顶点之间没有边‌。完全二分图 G m n G_m^n Gmn的m和n分别表示两个子集X和Y的顶点数。边数为 m × n m \times n m×n.

1.3 完美匹配

什么是完美匹配,指代一种能够覆盖图中所有顶点的特殊匹配结构。

二分图场景‌:在二分图中,若两部分的顶点数量相等,且存在一个匹配集合M(里面元素都是边)同时覆盖两部分的全部顶点,则该匹配称为完美匹配‌。

1.4 最大匹配

什么是最大匹配,有些情况下做不到完美匹配,只能尽量实现最多的配对,叫最大匹配。
总结,完美匹配一定是最大匹配,而最大匹配不一定是完美匹配。

1.5 顶点全覆盖‌

顶点全覆盖‌:图中边的集合,使得每个顶点恰好与一条边相关联,不存在未被覆盖的顶点。

1.6 增广路径

这是图论中用于求解二分图最大匹配问题的核心概念,其定义需满足以下条件:

  • 路径结构‌:连接两个‌未匹配顶点‌的路径,且路径上的边‌交替‌属于匹配边与非匹配边‌。
    例如,路径形如:未匹配顶点→可匹配边→已匹配边→…→可匹配边→未匹配顶点。如图下所示:
    在这里插入图片描述

  • 长度特性‌:路径长度为‌奇数‌(边数为奇数),其中可选匹配边数量比已匹配边多一条‌.

1.7 交错路径概念

给定图G的一个匹配集合M(放的元素都是边),如果一条路径的边交替出现在M中和不出现在M中,我们称之为一条M-交错路径

而如果一条M-交错路径,它的两个端点都不与M中的边关联,我们称这条路径叫做M-增广路径

举个例子:
在这里插入图片描述
上图有五条边,只有2和4在已匹配集合M里,1、3和5都是可选匹配。

  • 已匹配边:2和4
  • 可选匹配边:1、3和5

你会发现1、3以及5也可以是一个匹配集合。总体来看1、2、3、4以及5这条路径是匹配集合M的一条交错路径,同时它还满足两个端点不与M中的边所关联

既然这样就可以从1, 2, 3, 4以及5 这条路径中找到一个更大的匹配,而这个匹配比原先的匹配集合M多一条边,将是一个比原先M更大的匹配集合。

回顾我们的目标,是在确定的已匹配集合下寻找新的增广路径,因为出现一条增广路径,意味目前匹配中增加一条边。

这种复杂问题的求解思路,变成了寻找增广路径。当图中再也没有增广路径了,就意味着我们找到了该图的最大匹配。

我们这里所讨论的匹配,是图论中的任务分配问题,通常是针对于二部图发起的,想想也是,匹配不就是配对么,自然是两两成对了。

2. 历史背景与术语起源

  • 原始匈牙利算法‌:由Kuhn于1955年提出,‌专门针对无权二分图的最大匹配问题‌,通过寻找增广路径实现顶点全覆盖‌。
  • 改进版算法(KM算法)‌:Munkres在1957年引入‌权重处理机制‌,通过顶标调整与辅助矩阵优化,扩展至带权二分图的最小/最大权重匹配场景,故称为Kuhn-Munkres(KM)算法或Munkres算法‌

3.原始匈牙利算法

3.1 例解

初始化化一个图,它们的待匹配关系如下:

在这里插入图片描述
我们是基于二部图来讨论,上图就是这样的二部图,顶点集合分两类,X集合和Y集合

  • X集合:x1,x2,…,x6
  • Y集合:y1,y2,…,x7

我们的目标:是 尽可能多 地给X集合找到匹配顶点。注意,最大匹配是互相的,如果X集合能尽量多地匹配到Y集合,反过来,Y集合也不可能有更多地匹配到X集合。那我们开始做分步匹配说明:

step 1:刚开始,已匹配集合M肯定一个点都没有,我们随意选取待匹配集合的一条边,如(x1,y1)这条边,构建最初的匹配结果出来,如下图所示,已匹配的边用粗线标出:
在这里插入图片描述

step 2:接着给x2添加匹配,如下图的(x2,y2)边。
在这里插入图片描述
目前很顺利,到这里,我们的已匹配集合M,里面已经有(x1,y1)与(x2,y2)两条边。

step 3:然后我们想给x3顶点添加匹配,发现x3有待匹配边3条,按顺序从左到右,其中第一条待匹配边(x3,y1)中的y1已经被step1的x1顶点占用了,那么x3要强抢y1,建立(x3,y1)已匹配关系,那么(x1,y1)的匹配关系消失了,这时候x1另谋出路,发现自己还有另外两条可以匹配的关系,按顺序从左到右,发现(x1,y2),但是y2已经被x2占用了,同样事情发生了,x1强抢y2,x2需要自谋生路,非常好,x2也发现了自己还有一个可以匹配的关系(x2,y5),y5情况是无人占领,非常好,这一步到此结束,很明显这个寻找过程是递归形式。匹配如下所示:
在这里插入图片描述

我们把刚才涉及讨论到的顶点都拿出来:(x3,y1,x1,y2,x2,y5),很明显,这是一条路径P。
在step2中,我们已经有匹配集合M,而P呢,就是M的一条增广路径。

前面提过,若发现了一条增广路径,意味着出现了数目更多的匹配关系。于是这里的step3中,我们把M中的配对点拆除,重新组合,得到了一个比step2更大的匹配集合M,里面元素是(x3,y1),(x1,y2),(x2,y5)这三条边。

这就是原始匈牙利算法的核心关键。

依葫芦画瓢,x4,x5按顺序加进来,最终得到本图的最大匹配关系,如下图所示:
在这里插入图片描述
另外我们也能发现,如果把y4让给x6,x5会没有匹配关系了,但不影响最大匹配关系。

总结,匈牙利算法就是为了寻找最大匹配,通过不断寻找原有匹配M的增广路径,因为找到一条M匹配的增广路径,意味出现一个更大的匹配M’,恰好比M多一条边。另外我们也发现了,最大匹配不是唯一,但最大匹配的大小却是唯一的。

4.改进的匈牙利算法(KM算法)

求解指派任务中时间最小或者成本最低的问题。

4.1 解法概要

step 1: 变换效率矩阵,使得每行每列至少有一个零

  • 行变换:找出每行最小元素,从该行各元素中减去
  • 列变换:找出每列最小元素,从该列各元素中减去

step2:找出独立零元素(不在同行同列的零),并用直线覆盖全部零元素
技巧:行有独立划掉列,列有独立划掉行

step3:再变换矩阵来增多独立零元素个数

  • 在未划线的元素中找出最小元素
  • 未划线的各个元素减去这个最小元素
  • 交叉划线的元素均加上这个最小元素

4.2 例解

在这里插入图片描述

step 1: 变换效率矩阵,使得每行每列至少有一个零

  • 行变换:找出每行最小元素,从该行各元素中减去
  • 列变换:找出每列最小元素,从该列各元素中减去
    在这里插入图片描述

step2:找出独立零元素(不在同行同列的零),并用直线覆盖全部零元素

技巧:行有独立划掉列,列有独立划掉行

  • 先看第一行,第一行有独立的零,把零框出来,然后把该列划掉(行有独立划掉列)
    在这里插入图片描述
    这么划的意义是什么?结合例题来解释,就是一项工作只能由一个人来完成,那么这个工作已经指派给了这个人,其他人就不用负责了,所以把这一列划掉。
  • 接着看第二行,其中第一列被划掉,故第二行第一列元素不用管,那么只看4,5以及0。接着显然这行有独立零元素,同样做法,把零框出来,然后把该列划掉(行有独立划掉列)。如下所示:
    在这里插入图片描述
  • 然后看第三行,由于前面两步已经把第一列和第四列划掉,那么第三行,只有元素0和0.这属于不是独立零的情况,那么我们就不划了。
  • 再看第四行,同样判断做法,只有元素3和6,没有独立零,我们也不划了。
  • 现在我们换矩阵的列方向来看,可以看到第二列是有独立零的: [ 1 , 4 , 0 , 5 ] T [1,4,0,5]^T [1,4,0,5]T,按照口诀,把零框出来,列有独立划掉行。可以得到:
    在这里插入图片描述
    说明第二项任务指派了给第三人来完成。
  • 第三列已经没有零了,我们回过头来看总体,整个矩阵,只框出3个零出来,但是这是4阶方阵,我们需要四个零,故我们需要进行step3。

step3:再变换矩阵来增多独立零元素个数

  • 首先在未划线的元素中找到最小元素。我们结合上面最终得出的矩阵可以看到,最小元素就是1
  • 然后在没划线的各个元素 减去 这个最小元素。
  • 最后处在交叉划线的元素,要 加上 这个最小元素

我们可以看到,矩阵是长这样的变化,得到了一个新的矩阵 c i j 2 c_{ij}^2 cij2,这将放在step4中求解。
在这里插入图片描述

step4:找出独立零元素,再检验

在这里插入图片描述
从图上可以看到新的矩阵 c i j 2 c_{ij}^2 cij2,接下来我们接着看看怎么求解:

  • 第1,3以及4行没有独立零,只有第2行有独立零,故做法同样,框出独立零,行有独立划掉列,得到:
    在这里插入图片描述
  • 现在从矩阵的列方向看,可以看到第一列有独立零,故做法同样,框出独立零,列有独立划掉行,得到:
    在这里插入图片描述
  • 接着我们看第二列,同样做法,由于第一行元素在上面那一步被划掉,故第二列第一行的元素不用管,那么第二列只剩下 [ 3 , 0 , 2 ] T [3,0,2]^T [3,0,2]T,出现了独立零,老规矩,框出独立零,列有独立划掉行,得到:在这里插入图片描述
  • 从上面的矩阵图可以看到,还是只有三个独立零。独立零元素本应该未n阶方阵的n个,故本例还没有达到最优解。

step5:再变换矩阵来增多独立零元素个数

如同step3一样

  • 首先在未划线的元素中找到最小元素。我们结合上面最终得出的矩阵可以看到,最小元素就是1
  • 然后在没划线的各个元素 减去 这个最小元素。
  • 最后处在交叉划线的元素,要 加上 这个最小元素

得到新矩阵 c i j 3 c_{ij}^3 cij3
在这里插入图片描述

step6 :找出独立零元素,再检验

接着上面的新矩阵 c i j 3 c_{ij}^3 cij3,我们继续

  • 可以看到矩阵第1,2以及3行都没有独立零,只有第4行,老规矩,框零元素,行有独立划掉列,得到:
    在这里插入图片描述

  • 注意 :刚才上面划掉了第4列,可以发现,第二行这时候出现独立零了(因为第四列全部元素被划掉,包括第二行第四列的零元素),此时第二行元素为[0,2,3],那么老规矩,框零元素,行有独立划掉列,得到:
    在这里插入图片描述

  • 注意 :刚才上面划掉了第1列和第4列,可以发现,第一行这时候出现独立零了,此时第一行元素为[0,1],那么老规矩,框零元素,行有独立划掉列,得到:
    在这里插入图片描述

  • 现在第三行有独立零了,框零元素,行有独立划掉列,可得到:在这里插入图片描述

注意 :其实你说是第三列有独立零也行,做成列有独立划掉行,也是没问题,因为我们已经解决了问题,框出的零已经有四个。

step7:写出结果及答案

在这里插入图片描述

4.3 衍生问题

  • 1.如果不是求最小值,是求最大值Max如何处理?
    这个好说,找出系数矩阵最大值M,然后令系数矩阵变为 m-系数矩阵各元素值,得到新的系数矩阵,再按照求解步骤走就行。

  • 2.系数矩阵如果不是方阵,如何处理?

    • 任务<人数:增加虚拟任务,虚拟任务对应的系数全部设为0
    • 人数<任务:增加虚拟人,虚拟人对应的系数全设为0
  • 3.若指定一个人做多个任务呢?
    这个也好说,如果一个人可以做k个事情,就把这个人的系数复制k份,相当于增加了虚拟人,如果不是方阵,接着增加虚拟任务。

  • 4.若某个人不能做某项工作呢?
    这个也好说,把问题转换为求解最小值后,如果第i个人不能做第j项任务,则把系数矩阵的元素 c i j c_{ij} cij设置为一个比系数矩阵中最大值大一些的数。

5.表上作业法与改进版匈牙利算法的区别

维度‌‌表上作业法‌‌改进版匈牙利算法‌
问题类型‌运输问题(多对多资源分配)指派问题(一对一或一对多匹配)
核心操作‌表格检验数计算与闭回路调整 ‌‌增广路径搜索与顶标动态调整 ‌‌
适用数据结构‌二维供需矩阵二分图或邻接表
优化目标‌最小化全局运输成本 ‌‌最大化匹配效率或权值 ‌‌

‌注‌:两者均为线性规划问题的特例解法,但针对不同场景设计,表上作业法侧重连续变量调运,而改进版匈牙利算法侧重离散匹配优化。

6.参考资料

  1. https://zhuanlan.zhihu.com/p/572858620
  2. https://zhuanlan.zhihu.com/p/668517725
  3. https://www.cnblogs.com/jamespei/p/5555734.html
  4. https://www.bilibili.com/video/BV1vB4y1X73q

相关文章:

  • 深度学习 从入门到精通 day_02
  • Google Test 与 Google Mock:C++ 测试与模拟的完美结合
  • 于 Jupyter 天地,借 NumPy 之手编织数据锦缎
  • 管家婆财贸ERP BB106.采购开票选单批量过滤
  • Linux之 grep、find、ls、wc 命令
  • [数据结构]哈希表
  • 3DMAX粒子流样条线生成器PFSpliner使用方法详解
  • 【AI News | 20250417】每日AI进展
  • 金蝶云星空API接口调试postman
  • Mybtis和Mybatis-Plus区别
  • 4月17日星期四今日早报简报微语报早读
  • 高效检测书签网址,告别无效链接烦恼
  • 新一代电子海图S-100标准
  • Python中如何加密/解密敏感信息(如用户密码、token)
  • C++面试
  • 蓝牙的AT指令
  • 第二届中国人形机器人与具身智能产业大会圆满闭幕,爱迪斯通动捕设备引瞩目
  • [终极版]Javascript面试全解
  • 【Dify 前端源码解读系列】MDX 让 API 文档焕发生机
  • jenkins凭据管理(配置github密钥)
  • 太空飞梭项目起火,南宁方特东盟神画:明火已扑灭,无人受伤
  • 家政阿姨如何炼成全国劳模?做饭、收纳、养老、外语样样都会
  • 夜读丨春天要去动物园
  • 投资者建议发行优惠套票给“被套”小股东,张家界:将研究考虑
  • 顺利撤离空间站,神十九乘组踏上回家之旅
  • 江西省公安厅警务保障部原主任辛卫平主动交代问题,正接受审查调查