【问题标题】:How to iterate over all these possibilities?如何迭代所有这些可能性?
【发布时间】:2016-07-24 12:27:32
【问题描述】:

假设我们有一个 python 列表

list = [[1,2,3],[4,5,6],[7,8,9]]

我将总和定义如下,

sum:是每个子列表中单个条目(不同索引)的总和。

这听起来很复杂,所以我举个例子,

对于上面的列表,1 + 5 + 9 是总和之一,因为 1 来自第一个子列表,5 来自第二个子列表,9 来自第三个子列表,它们在相应的子列表中都有不同的位置。

所以我不能拥有1 + 4 + 7,因为 1,4 和 7 是其子列表中的第一个条目。

我不能拥有1 + 5 + 8,因为 5 和 8 都是它们列表中的第二个条目,依此类推

例如, 我想找到每个子列表的单个条目总数的最高总和!

我怎样才能遍历所有这些可能的总和,然后从所有这些总和中得到最高的。

对于上面的列表,我们有 3^3=27 个不同的和。

有没有一种使用 python 的有效方法?

【问题讨论】:

  • 这似乎是您不想只是迭代并检查所有排列的那种事情。
  • 但如果我没有遍历所有内容,我将如何获得最高金额? @亚当史密斯
  • 这是寻路。 A * 也许?天真的实现虽然使用itertools.product
  • 这是寻路吗?这对我来说似乎不同 - 例如,如果您在示例中的节点“5”处,您不一定能根据您来自哪里去到 7 8 或 9。您需要一个指数级的大图来表示所有可能的“路径”,不是吗?
  • 为什么是 27 个总和,而不是 6 个?

标签: python algorithm


【解决方案1】:

这是一个经典问题,可以使用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) 中运行。

【讨论】:

    【解决方案2】:

    简单的实现使用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)
    

    【讨论】:

      【解决方案3】:

      我不知道执行效率,但是代码编写效率可以考虑:

      for k in itertools.permutations(lst):
          print(sum([j[i] for i, j in enumerate(k)]))
      

      仅适用于 OP 示例中的方形列表。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-01-18
        • 1970-01-01
        • 2011-11-22
        • 1970-01-01
        • 2010-09-27
        • 2016-06-01
        • 2011-11-14
        相关资源
        最近更新 更多