https://en.wikipedia.org/wiki/Hungarian_algorithm
http://www.hungarianalgorithm.com/index.php
匈牙利算法是解决分配问题(assignment problem)的算法,使用第二个网址中的例子讲解:
问题描述:我们公司有三项任务,要外包给三个工人,每个工人有不同的收费标准,比如任务1,复现mask rcnn,任务2,复现deeplabv3,任务3,复现resnet。三个炼丹师(a,b,c)分别收费如下表:
任务1 | 任务2 | 任务3 | |
---|---|---|---|
a | 78 | 87 | 38 |
b | 37 | 71 | 5 |
c | 50 | 97 | 66 |
老板又比较抠门,要求用最少的钱完成这三项任务。
我们尝试分配任务,力求每个人的花费都最低
匈牙利算法:
步骤1,subtract the row minimum from each row
对每个人减去最小花费值,
任务1 | 任务2 | 任务3 | ||
---|---|---|---|---|
a | 40 | 49 | 0 | (-38) |
b | 32 | 66 | 0 | (-5) |
c | 0 | 47 | 16 | (-50) |
也就是给a分配任务3,给b分配任务3,给c分配任务1,这时候显然是有问题的,任务三分配了两次
step 2: subtract the column minimum from each column
任务1 | 任务2 | 任务3 | |
---|---|---|---|
a | 40 | 2 | 0 |
b | 32 | 19 | 0 |
c | 0 | 0 | 16 |
(-47) |
step3: Cover all zeros with a minimum number of lines
发现只需要用最后一列和最后一行就可以将所有的0cover,说明任务和工人不能完全匹配
step4: Create additional zeros
在uncovered 数列中(a,b两行的前两列),减去他们的最小值,并将此值加到被cover两次的地方(第三部中第一列和最后一行的交叉处)
任务1 | 任务2 | 任务3 | |
---|---|---|---|
a | 38 | 0 | 0 |
b | 30 | 17 | 0 |
c | 0 | 0 | 18 |
重复步骤3、发现此时需要至少3行或者3列才能将所有0 cover
此时的最优分配是b任务3,a任务2,c任务1,87+5+50=142
一些实现方式:
c++
http://software.clapper.org/munkres/
python
https://github.com/xtof-durr/makeSimple/blob/master/Munkres/kuhnMunkres.py