匈牙利算法是一比较常见的求解指派模型或分配模型的算法.
相关的资料比较多,但很少有比较易于编写代码的.
这也就是俺这个文章的目的了,争取让大家照着就能画出代码来:)
⑴ 匈牙利算法步骤
① 矩阵规约.
遍历矩阵的行,求得各行的最小值,并对各行上的所有元素减去其最小值.
遍历矩阵的列,求得各列的最小值,并对各列上的所有元素减去其最小值.
② 统计各行列0元素个数
遍历各个行和列的元素,统计出各行和列的0元素个数.
③ 标记0操作.
遍历矩阵的行,找到只含一个0元素的行,将该0元素"画圆".
再遍历该0元素所在的列,将该列上的0元素"画撇".
遍历矩阵的列,找到只含一个0元素的列("画撇"的0元素不看作自由0元素).
再遍历该0元素所在的行,将该行上的0元素"画撇"
④ 如果"画圆"0的个数等于矩阵维数,则输出结果.即调用7.
如果还存在自由0元素,则调用7.
如果不存在自由0元素,且"画圆"0的个数少于矩阵维数,则调用5.
⑤ 用最少直线覆盖.
a.对没有"画圆"0元素的行打√号.
b.对已打√号的行中所有含"画撇"0元素的列打√号.
C.对打√号列上有"画圆"0元素的行打√号.
d.重复(b)(c)直到得不出新的打√号的行列为止.
e.打√号的列画纵线,没打√号的行画横线.
这就是覆盖所有0元素的最少直线集合.
⑥ 增加(转移)0元素.
a.求出未被直线覆盖的元素中的最小值k.
b.对打√行减去k,对打√列加上k
c. 转到第2步骤.
⑦ 剩余自由0元素处理
a.取存在自由0元素的行中的第一行(也可以取自由0元素最少的行)
b.遍历a中所选行,依次取该行中的自由0元素.
执行:
c.对该自由0元素进行画圆操作.
d.将该元素所在行列的其它自由0元素画撇
e.执行标记0操作,即调用③.
f.执行④进行转换.
⑧ 结果输出
按照"画圆"0元素的位置,纪录结果.
各个模块的调用流程:
具体示例: