假设您想用sum<;max_sum和{}和{}之间的元素数来查找输入的所有子集。在
这里有两种方法可以做到这一点,我包含了整个脚本以使它更易于测试和使用,但基本上您只需要*LimitedSums()函数就可以得到答案。在
暴力方法是iterate through all subsets,并检查每个子集的和和和元素数。这实际上就是SlowLimitedSums()所做的——尽管它利用itertools.combinations()来迭代子集,并且不考虑包含超过max_terms元素的子集。在
可能更有效的方法是只考虑总和小于max_sum的子集。如果您正在递归地构建子集,那么只要当前子集的和超过max_sum,假设所有输入数字都是非负的,或者元素的数量超过max_terms,就可以简单地停止递归。这是在^{中实现的。在
请注意,在最坏的情况下,您的结果将包含所有2^len(v)子集,在这种情况下,*LimitedSums()的两个版本之间应该没有明显的运行时间差。在import itertools
import random
def SlowLimitedSums(v, max_sum, min_terms=None, max_terms=None):
min_terms = 0 if min_terms is None else min_terms
max_terms = len(v) if max_terms is None else max_terms
return sorted(set(
sum(c) for nc in range(min_terms, max_terms + 1)
for c in itertools.combinations(v, nc)