本人在项目中,使用匈牙利算法,寻找最佳(损失最小)的完美匹配。即N匹配N。
参考以下了解匈牙利算法:
运筹学教学 | 十分钟教你求解分配问题(assignment problem) - 知乎
有一个python的实现:
https://python.plainenglish.io/hungarian-algorithm-introduction-python-implementation-93e7c0890e15
按照常规的算法逻辑实现,遇到的问题是:寻找不到完美匹配,但是覆盖所有0的横竖线的条数总和已达到了输入方阵的阶数N。
问题出在:在进行“指派”的时候,方案有很多种,一般来说,先指派0最少的行,输入矩阵的每一行可以理解成一个工人做不同任务的时间,每一列则是每一项任务,不同工人来做需要的时间。遵循选择多的“礼让”选择少的的原则,先指派0最少的行,再指派0多的行,我们将此指派策略为策略A;
但是这样指派的话,并不是最大的指派,也就是说,可能存在能够指派更多工人的指派。而且,如果这时候寻找到的覆盖所有0的横竖线等于方阵阶数N的时候,算法就停滞了,因为没办法增加0了(整个矩阵都被横竖线划掉了,不存在未被覆盖的元素)。我想的办法是,当按照“优先指派0少的行”进行指派,得不到完美匹配的时候,穷举所有的指派(当然,可以提前结束穷举,当指派的行数跟策略A有增加的时候可提前结束穷举指派的情况),然后再往下走。
穷举所有的指派,代码上用了递归,思路大概是:当前一行确定了指派某个0的时候,递归对下一行进行指派,最后一行指派完之后,当前这一次指派就结束了,存到数组里。