1、指派问题概述
有n项不同的任务,需要n个人分别完成其中的1项,每个人完成任务的时间不一样。于是就有一个问题,如何分配任务使得花费时间最少。
通俗来讲,就是n*n矩阵中,选取n个元素,每行每列各有1个元素,使得和最小,如图表示:
2、指派问题性质
最优解一般满足:若从矩阵的一行(列)各元素中分别减去该行(列)的最小元素,得到归约矩阵,其最优解与原矩阵的最优解相同。
3、匈牙利法流程图
4、代码实现
在多目标跟踪时,我们得到了上一帧的多个Bbox与这一帧的多个Bbox的IOU矩阵,需要找到最大IOU组合的索引对,这时我们使用匈牙利算法来计算。
import numpy as np
def linear_assignment(X):
"""
使用匈牙利算法解决线性指派问题。
"""
indices = _hungarian(X).tolist()
indices.sort()
# Re-force dtype to ints in case of empty list
indices = np.array(indices, dtype=int)
# Make sure the array is 2D with 2 columns.
# This is needed when dealing with an empty list
indices.shape = (-1, 2)
return indices
class _HungarianState(object):
"""
执行匈牙利算法的状态.
"""
def __init__(self, cost_matrix):
cost_matrix = np.atleast_2d(cost_matrix) # 2维矩阵
# 如果行大于列,算法则不能正常工作。需要转换过来。
transposed = (cost_matrix.shape[1] < cost_matrix.shape[0])
if transposed:
self.C = (cost_matrix.T).copy()
else:
self.C = cost_matrix.copy()
self.transposed = transposed # 记录这个标志
# 此时 m >= n.
n, m = self.C.shape
self.row_uncovered = np.ones(n, dtype=np.bool)
self.col_uncovered =