【问题标题】:Python - Finding out all r combinations from a set of cardinality n [duplicate]Python - 从一组基数 n 中找出所有 r 组合 [重复]
【发布时间】:2021-12-01 06:16:24
【问题描述】:

我正在尝试使用递归从集合 {1,2,3,4,5} 中生成所有可能的 3 种组合。

预期输出:[[1,2,3],[1,2,4],[1,2,5],[2,3,4],[2,3,5],[3, 4,5],[1,3,4],[1,3,5],[1,4,5],[2,4,5]]

我使用的逻辑是任何 3-set 组合要么包含第一个元素,要么不包含。我也在使用列表的串联。示例:

[[1,2,3]] + [[a,b]] 给出 [[1,2,3],[a,b]]

使用上述逻辑的以下代码似乎不起作用。我是自学的,如有错误,请多多包涵。我知道我的递归中有错误。但是,尝试回溯递归问题的输出对我来说非常困难。 您能否让我知道该程序的缺陷可能在哪里,并指导我寻找可以更好地处理此类问题的合适资源。在这些问题中正确的思维方式是什么?非常感谢您的帮助。

代码:

sol = [1,2,3,4,5]
b=3

y= []
def combinations(sol, b):
    global y
    if len(sol) == b or len(sol)==1 :
        return [sol]
    y.append([[sol[0]] + combinations(sol[1:], b-1)] +  combinations(sol[1:],b))
    return y

print(combinations(sol,b)

【问题讨论】:

  • y 保存您的整个组合列表,并在每次通话期间不断增长。您不希望 combinations 返回 y。想想y.append 调用中的作用。另外,你不需要global y;您没有将新对象分配给 y
  • 您不能真正使用递归来创建所有组合的集合,尽管您可以使用它来生成单独的组合。请记住,您需要一个循环;您的第一次调用将生成 [1] 加上列表的其余部分,[2] 加上列表的其余部分,以及 [3] 加上列表的其余部分。你没有这样做。

标签: python recursion


【解决方案1】:

使用itertools中提供的机器:

from itertools import combinations

list(combinations(v, 3))

输出

[(1, 2, 3), (1, 2, 4), (1, 2, 5), (1, 3, 4), (1, 3, 5), (1, 4, 5), (2, 3, 4), (2, 3, 5), (2, 4, 5), (3, 4, 5)]

【讨论】:

    【解决方案2】:

    你可以通过让你的函数成为一个生成器来做到这一点。在每一步中,您循环遍历可能的起始单元格,然后遍历递归中下一步返回的结果。

    sol = [1,2,3,4,5]
    b=3
    
    def combinations(sol, b):
        if b == 0:
            yield []
        else:
            for i in range(len(sol)-b+1):
                for j in combinations(sol[i+1:],b-1):
                    yield [sol[i]]+j
    
    print(list(combinations(sol,b)))
    

    输出:

    [[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], [1, 4, 5], [2, 3, 4], [2, 3, 5], [2, 4, 5], [3, 4, 5]]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多