假设我们有一个python列表
list = [[1,2,3],[4,5,6],[7,8,9]]
我将总和定义为以下内容,
sum:是每个子列表中单个条目(不同索引)的总和。
这听起来很复杂,所以我举一个例子,
对于上面的列表,1 + 5 + 9是总和之一,因为1来自第一个子列表,5来自第二个子列表,9来自第3个子列表,它们在相应的子列表中都有不同的位置。
所以我不能1 + 4 + 7
因为1,4& 7是他们的子列表中的第一个条目。
我无法1 + 5 + 8
,因为5& 8是他们列表中的第二个条目,依此类推
我想找到每个子列表中各个条目总数的最高总和!!
如何迭代所有这些可能的总和,然后从所有这些总和中获得最高分。
对于上面的列表,我们有3 ^ 3 = 27个不同的总和。
使用python是否有一种有效的方法?
答案 0 :(得分:8)
这是一个可以使用Hungarian algorithm解决的经典问题。 sklearn中有一个实现:
from sklearn.utils.linear_assignment_ import linear_assignment
import numpy as np
M = [[1,2,3],[4,5,6],[7,8,9]]
M = np.array(M) #convert to numpy array
result = linear_assignment(M)
answer = sum(M[cell[0]][cell[1]] for cell in result)
迭代所有可能的总和是一个坏主意(O(N!))。上面的算法必须在O(N ^ 3)中运行。
答案 1 :(得分:0)
天真的实现使用itertools.product
生成所有可能的配对,然后过滤掉由于索引问题而无效的配对。
from itertools import product
lst = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
with_indices = [ [(idx, val) for idx, val in enumerate(sublst)] for sublst in lst]
# [ [(0, 1), (1, 2), (2, 3)],
# [(0, 4), (1, 5), (2, 6)],
# [(0, 7), (1, 8), (2, 9)] ]
total_product = product(*with_indices)
filtered_product = [
[p[0][1], p[1][1], p[2][1]] for p in total_product if
len(set([p[0][0], p[1][0], p[2][0]])) == 3]
# p[0][1], p[1][1], p[2][1] refers to original values
# p[0][0], p[1][0], p[2][0] refers to original indices
# asserting the length of the set of indices is 3 ensures that all are unique.
# [[1, 5, 9],
# [1, 6, 8],
# [2, 4, 9],
# [2, 6, 7],
# [3, 4, 8],
# [3, 5, 7]]
result = max(filtered_product, key=sum)
答案 2 :(得分:0)
我不知道执行效率,但是对于代码编写效率,您可以考虑:
for k in itertools.permutations(lst):
print(sum([j[i] for i, j in enumerate(k)]))
仅适用于OP示例中的方形列表。