干货|一文搞懂Hungarian Algorithm匈牙利算法
匈牙利算法简介
匈牙利算法是一种在多项式时间内(
接下来,我们将举例介绍这个算法。
问题的引入
首先,我们来考虑一个问题。
假设你是一个网络服务的供应商,你们可以免费给用户装Wi-Fi。现在呢,有三家用户要装Wi-Fi,同时,你有三个装Wi-Fi的工人在附近。
注:
Job —> 装Wi-Fi
Worker —> 工人
每个工人前往用户家装Wi-Fi需要一定开销(比如,油费,车费等等)。开销见下图。
用矩阵表示为
作为一个商人,你肯定想的是,要怎么分配可以最省钱呢?你会通过比较不同分配方案的开销,选择最省钱的那个作为分配方案。
注意:分配时,每个工人只安装一户人家的Wi-Fi。
对于每一个分配方案,我们都可以计算出它的总开销。在这个问题中,一共有6种分配方案,如下图所示。
我们最终选择总开销最小的方案,即第4个方案。最小总开销为70。
现在,找到了最小开销的分配方案,解决了问题。但你是不是觉得,这样算起来特别麻烦呢?
现在是一个3*3的矩阵,n=3,那么n=1000,10000呢?
一共要计算n*(n-1)*(n-2)*..*1次,效率是0(n!),这太糟糕了!
为了更高效地解决这个问题,我们是时候搬出匈牙利算法了。
用匈牙利算法求解任务分配问题(一)
好,我们来看看匈牙利算法是怎么解决这个问题的。
第一步:Row reduction
每一行减去这一行的最小值。
那么现在每一行至少有一个0。
第二步:Column reduction
每一列减去这一列的最小值。
好,现在每一列至少有一个0。
第三步:Test for an optimal assignment
这一步,我们要用最少的直线把矩阵中的零都给覆盖了。
如果直线的数量=n,我们就可以得到一个最优方案了。那就直接跳过第4步,直达第5步。
在这个例子里,最少直线数
第五步:Making the final assignment
我们选择3个不在同一行,同一列的0就行。被选择的这些0代表了最终的分配方案。即,
当第三步最少直线数 <n时呢我们换一个例子来说明。
用匈牙利算法求解任务分配问题(二)
第一步:Row reduction
每一行减去这一行的最小值。
那么现在每一行至少有一个0。
第二步:Column reduction
每一列减去这一列的最小值。
好,现在每一列至少有一个0。
第三步:Test for an optimal assignment
这一步,我们要用最少的直线把矩阵中的零都给覆盖了。
这次,最少直线数
第四步:Shift zeros
我们需要至少转移一个
首先,我们找出没被直线覆盖的值中的最小值。
在本例中为5。
接下来,每个未被直线覆盖的值都减去这个最小值。然后在直线交叉处加上这个最小值。
最后我们把直线移除,回到第三步。
第三步:Test for an optimal assignment
这一步,我们要用最少的直线把矩阵中的零都给覆盖了。
这次,最少直线数
第五步:Making the final assignment
我们选择
这些方案都是可行的,它们的开销都等于最小开销。即,
用匈牙利算法求解任务分配问题(三)
还有一个问题,如果工人数和任务数不相同呢?我们该怎么用匈牙利算法?
答:
我们只需要用0填充缺失的行或列就行。然后记得在第五步确定最终分配方案时,把它们移除。
推荐阅读:
连载笔记|MIT线性代数课程精细笔记[第七课]-Ax=b的解讨论
欢迎关注公众号学习交流~
欢迎加入交流群交流学习