如何迭代所有这些可能性?

时间:2016-07-24 01:41:39

标签: python algorithm

假设我们有一个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是否有一种有效的方法?

3 个答案:

答案 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示例中的方形列表。