【问题标题】:How to calculate the number of all possible combinations for a range of numbers from 1 to N?如何计算从 1 到 N 的数字范围内所有可能组合的数量?
【发布时间】:2015-06-15 14:06:35
【问题描述】:

除了这样做:

from itertools import combinations
def brute_force(x):
    for l in range (1,len(x)+1):
        for f in list(combinations(range(0,len(x)),l)):
            yield f
x = range(1,18)
len(list(brute_force(x)))

[出]:

131071
  • 如何数学计算所有可能组合的数量?

  • 有没有一种方法可以在不列举可能的组合的情况下进行计算?

【问题讨论】:

  • itertools.combinations: 返回的项目数是n! /r! /(n-r)!当 0 n 时为零。 你为什么要将 combinations(range(0,len(x)),l) 转换为 list

标签: python math combinations itertools


【解决方案1】:

总是有 2n-1 个非空子集 {1,...,n}

例如考虑列表['a','b','c']

>>> [list(combinations(['a','b','c'],i)) for i in range(1,4)]
[[('a',), ('b',), ('c',)], [('a', 'b'), ('a', 'c'), ('b', 'c')], [('a', 'b', 'c')]]
>>> l=[list(combinations(['a','b','c'],i)) for i in range(1,4)]
>>> sum(map(len,l))
7

我们的列表长度为 3,所以我们有 23-1=7 个组合。

对于range(10)

>>> l=[list(combinations(range(10),i)) for i in range(1,11)]
>>> sum(map(len,l))
1023      #2^10-1 = 1024-1=1023

请注意,如果您想计算空子集,您可以使用 2^n

实际上是从数学的角度来看:

集合的 k 组合是 S 的 k 个不同元素的子集。如果集合有 n 个元素,则 k 组合的数量等于 binomial coefficient

对于所有组合:

【讨论】:

  • 注:这是正确的答案。 OP 不只是生成固定大小的组合,而是对 all 组合求和。 (也就是说,不仅仅是choose(n, k),而是sum(choose(n,k), k=1..n))。
  • 为什么是“-1”呢?空集对你犯了什么罪? ;)
  • 是的,开个玩笑。您可能希望链接到 Wikipedia 中的 Binomial Theorem 页面。我们可以代入 x=1 和 y=1 并轻松证明 2^n = comb(n,0) + comb(n,1) + ... comb(n,n)
  • @ypercube ;),我就是这么做的!固定!
【解决方案2】:

假设您有一个来自[1, 10) 的列表,并且您想选择3 的项目

数学

>>> math.factorial(9) // (math.factorial(3) * math.factorial(6))
84

这是combinations的定义

_____n!_____
 k!(n - k)!

所以作为一个通用函数

def num_combinations(n, k):
    return math.factorial(n) // (math.factorial(k), math.factorial(n-k))

蛮力

>>> len(list(itertools.combinations(range(1,10), 3)))
84

【讨论】:

  • 您可能希望使用// 而不是/,否则您将在 Python 3 上得到不正确的结果。
猜你喜欢
  • 2021-04-23
  • 1970-01-01
  • 1970-01-01
  • 2022-08-06
  • 1970-01-01
  • 1970-01-01
  • 2021-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多