我正在寻找一种方法来找到所有和的组合,其中Fibonacci序列的元素具有等于相同值的给定限制。我知道来自combinations()
的{{1}}是解决此类问题的最佳选择,但由于我是Python的新手,我想知道如何保留匹配组合(因为只有一个是正确的,因为这不是算法的结束)。
我目前有:
itertools
现在我知道第二位在很多方面都是错误的。另外,我犯了一个错误,试图将元组添加到整数。我只需要知道如何使用itertools模块分别迭代这些组合的单独元素。只有sum'n'的组合对我有用。
答案 0 :(得分:1)
如果我正确理解您要实现的目标,请使用以下代码:
def zeckendorf(n):
seq = fib1(n)
for i in range(1, len(seq)):
for comb in itertools.combinations(seq, i):
if sum(comb) == n:
return list(comb)
return []
如果您需要进一步解释此代码,请询问:)
答案 1 :(得分:1)
要查找所有所需总和的组合,请将每个组合附加到结果列表中:
def combinations_with_sum(sequence, desired_sum):
results = []
for i in range(len(sequence)):
results.extend([combination for combination in combinations(sequence, i)
if sum(combination) == desired_sum])
return results
答案 2 :(得分:0)
让我们假设您要查找输入的所有子集,并且< max_sum
以及min_terms
和max_terms
之间的元素数量。
以下是一些方法,我包括整个脚本,以便更容易测试和使用,但基本上你只需要* LimitedSums
()函数来获得答案。
蛮力方法是iterate through all subsets并检查每个子集的总和和元素数量。这实际上是SlowLimitedSums()
所做的 - 尽管它利用itertools.combinations()
来迭代子集,并且不会考虑具有超过max_terms
个元素的子集。
潜在的更有效的方法是仅考虑总和小于max_sum
的子集。如果要递归构建子集,只要当前子集的总和超过max_sum
,就可以立即停止递归,假设所有输入数字都是非负数,或者元素数超过max_terms
。这是在FasterLimitedSums()
。
请注意,在最糟糕的情况下,您的结果将包含所有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)
if sum(c) <= max_sum))
def FasterLimitedSums(v, max_sum, min_terms=None, max_terms=None):
l = sorted(v)
n = len(v)
min_terms = 0 if min_terms is None else min_terms
max_terms = n if max_terms is None else max_terms
result = set([])
def RecursiveSums(s, n_terms, start_pos):
if start_pos >= n or s > max_sum or n_terms > max_terms:
return
if n_terms >= min_terms:
result.add(s)
for p in range(start_pos, n):
RecursiveSums(s + v[p], n_terms + 1, p + 1)
RecursiveSums(0, 0, -1)
return sorted(result)
def main():
mass_list = [4, 1, 8]
mass = 10
print(sorted(mass_list + SlowLimitedSums(mass_list, mass, min_terms=2)))
print(sorted(mass_list + FasterLimitedSums(mass_list, mass, min_terms=2)))
if __name__ == "__main__":
main()