【问题标题】:How to recursively check all combinations of list python如何递归检查列表python的所有组合
【发布时间】:2015-01-28 22:44:55
【问题描述】:

我正在尝试编写代码来递归检查一个列表是否可以分为两个具有相同总和的子列表,因此需要传递列表的所有组合,例如:[1,2,3,4] 所以我需要检查:

1------2,3,4

1,2------3,4

1,3-----2,4

等等.... 但我找不到如何做到这一点的方法。

【问题讨论】:

  • 为什么不是 1、4 和 2、3 和 1、2、3 和 4 等等等等
  • 我猜“等等”是指“等等”,所以 1,4 和 2,3 和 1,2,3 也是有效的,只是没有明确提及。跨度>
  • itertools.permutations 和朋友可以帮助你。

标签: python recursion backtracking


【解决方案1】:

递归检查一个列表是否可以分成两个总和相同的子列表

您可以使用递归轻松实现greedy partition algorithm:

def _greedy_part(r, sa, la, sb, lb):
    if not r:
        return sa == sb, la, lb;

    if sb < sa:
        # swap both lists in order to always have
        # the "lower sum list" as sa/la
        sb, sa = sa, sb
        lb, la = la, lb

    return _greedy_part(r[1:], sa+r[0], la+r[0:1], sb, lb)

def greedy_part(r):
    return _greedy_part(sorted(r,reverse=True), 0, [], 0, [])

关键思想是始终将最大的剩余值添加到总和最小的列表中。再一次,该解决方案在 Python 中表现不佳,因为函数调用效率不高,而且 Python 没有 tail call optimization。

鉴于样本测试:

print(greedy_part([1,2,3,4]))
print(greedy_part([1,2,3,4,5]))
print(greedy_part([6,1,2,3]))

它将产生:

(True, [4, 1], [3, 2])
(False, [5, 2, 1], [4, 3])
(True, [3, 2, 1], [6])

【讨论】:

    【解决方案2】:

    蛮力:

    import itertools
    
    seq = [1, 2, 3, 4]
    S = sum(seq)
    for i in xrange(1, len(seq)):
        for c in itertools.combinations(seq, i):
            print c, 2*sum(c) == S
    

    不过,这不是解决问题的最有效方法。阅读:http://en.wikipedia.org/wiki/Partition_problem

    【讨论】:

      【解决方案3】:

      你可以使用

      1. simleo 建议的 itertools。这是蛮力解决方案,将在指数时间内运行。

      2. 使用给定 here 的传统子集问题解决方案,运行时间为 (total_sum_of_nums)*len(list) 时间

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-02
        • 2013-06-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多