西皮的linear_sum_assignment给出不正确的结果



当我如图所示尝试使用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])

来自rowcol的相应索引对给出所选择的条目。也就是说,所选择的条目的索引是(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是";答案";。但是,通常情况下,答案涉及两个返回的数组。

最新更新