当我如图所示尝试使用scipy.optimize.linear_sum_assignment
时,它给出了总成本为15的分配向量[0 2 3 1]
。
然而,从成本矩阵c
中,您可以看到,对于第二个任务,第五个代理的成本为1
。因此,预期的分配应该是[0 3 None 2 1]
(9的总成本(
为什么linear_sum_assignment
没有返回最佳分配?
from scipy.optimize import linear_sum_assignment
c = [
[1, 5, 9, 5],
[5, 8, 3, 2],
[3, 2, 6, 8],
[7, 3, 5, 4],
[2, 1, 9, 9],
]
results = linear_sum_assignment(c)
print(results[1]) # [0 2 3 1]
linear_sum_assignment
返回一个由两个数组组成的元组。这些是指定值的行索引和列索引。例如(c
转换为numpy数组(:
In [51]: c
Out[51]:
array([[1, 5, 9, 5],
[5, 8, 3, 2],
[3, 2, 6, 8],
[7, 3, 5, 4],
[2, 1, 9, 9]])
In [52]: row, col = linear_sum_assignment(c)
In [53]: row
Out[53]: array([0, 1, 3, 4])
In [54]: col
Out[54]: array([0, 2, 3, 1])
来自row
和col
的相应索引对给出所选择的条目。也就是说,所选择的条目的索引是(0,0(、(1,2(、(3,3(和(4,1(。正是这些对是";分配";。
与此分配相关的总和为9:
In [55]: c[row, col].sum()
Out[55]: 9
在问题的原始版本中(但经过编辑(,看起来您想知道每列的行索引,所以您期望[0,4,1,3]。您想要的值在row
中,但顺序不是您所期望的,因为col
中的索引不仅仅是[0,1,2,3]。要获得预期形式的结果,必须根据col
中索引的顺序对row
中的值进行重新排序。这里有两种方法。
第一:
In [56]: result = np.zeros(4, dtype=int)
In [57]: result[col] = row
In [58]: result
Out[58]: array([0, 4, 1, 3])
第二:
In [59]: result = row[np.argsort(col)]
In [60]: result
Out[60]: array([0, 4, 1, 3])
请注意,linear_sum_assignment
文档字符串中的示例可能具有误导性;因为它在python会话中只显示col_ind
,所以给人的印象是col_ind
是";答案";。但是,通常情况下,答案涉及两个返回的数组。