繁体   English   中英

从数字列表中生成所有可能组合的百分比

[英]Generate a percent of all possible combinations from a list of numbers

我知道itertools.combinations(iterable, r)返回元素列表/元组的组合(作为可迭代对象)。 如何围绕它构建一个仅返回所有组合的 x% 的函数? (我只需要一个元组列表,所以它不必是迭代器)。 我希望如果有很少的组合,例如 nCn,它应该返回所有(在这种情况下是一个)(因此最少为 1)。

使用itertools.islice您可以生成具有元素数量上限的迭代器:

import itertools

MAX_COMBS = 2
combs = itertools.combinations(range(3), 2)
combs_slice = itertools.islice(combs, MAX_COMBS)
print(*combs_slice, sep='\n')
# (0, 1)
# (0, 2)

如果迭代的大小有一个len ,那么你可以根据组合的总数来设置上限:

import itertools
import math

# Percentage of combinations to draw
COMB_RATIO = 0.2
# Lower bound for number of combinations
MIN_COMBS = 2

iterable = range(5)
k = 3
combs = itertools.combinations(iterable, k)
max_combs = max(round(COMB_RATIO * math.comb(len(iterable), k)), MIN_COMBS)
combs_slice = itertools.islice(combs, max_combs)
print(*combs_slice, sep='\n')
# (0, 1, 2)
# (0, 1, 3)
# (0, 1, 4)

iterable = range(3)
k = 2
combs = itertools.combinations(iterable, k)
max_combs = max(round(COMB_RATIO * math.comb(len(iterable), k)), MIN_COMBS)
combs_slice = itertools.islice(combs, max_combs)
print(*combs_slice, sep='\n')
# (0, 1)
# (0, 2)

注意: math.comb是在 Python 3.8 中引入的,如果您在以前的版本中,您可能需要推出自己的实现,或者从 SciPy 等获取它。

因为迭代器不携带它们的集合有多长的信息,所以你不能从中获取长度。

在您的情况下,您可以使用公式 n!/(k! (nk)!) 确定组合的大小并迭代直到您的百分比。

例如:

from math import factorial, ceil

def my_combinations():
    ratio = .2 # 20 percent
    a = range(10)
    n = len(a)
    k = 5
    it = itertools.combinations(a, k)
    total_combinations = factorial(n) / factorial(k) / factorial(n-k)

    for _ in range(ceil(total_combinations * ratio)):
        yield it.next()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM