2 回答

TA貢獻1818條經驗 獲得超3個贊
我可能沒有完全理解這個問題,但是,如果我理解了,這種完全不同的方法可以在幾秒鐘內解決N=8,實例。D=25
>>> sum(1 for x in gensums(4, 16))
455
似乎與您的代碼返回的內容相匹配,并且
>>> sum(1 for x in gensums(8, 25))
346104
上次運行的示例x:
[9, 2, 3, 1, 1, 1, 1, 7]
這在嘗試擴展部分解決方案的過程中使用遞歸來應用約束,因此可以提前切斷許多無結果的路徑。
注意:為了提高效率,它產生的列表通常是同一個列表對象,所以如果你想保存結果供以后使用,一定要復制每個結果。
編輯:替換為更快的版本,也許更清晰一些。
編輯:還有一個改進:添加nslots == 1允許斷言的情況remaining并且nslots在函數入口處都是非零的。
def gensums(N, D):
def inner(sofar, nslots, remaining):
assert remaining and nslots
# If only 1 slot left, it's forced.
if nslots == 1:
sofar.append(remaining)
yield sofar
sofar.pop()
return
# If num slots equal to remaining, they must all be 1.
if nslots == remaining:
yield sofar + [1] * remaining
return
# What can we add next?
# What's left over must be enough to put at least 1 into
# each slot, so must have:
# remaining - candidate >= nslots - 1, or
# candidate <= remaining - nslots + 1
sofar.append(None)
for candidate in range(1, remaining - nslots + 2):
sofar[-1] = candidate
yield from inner(sofar, nslots - 1,
remaining - candidate)
sofar.pop()
return inner([], N, D)

TA貢獻1842條經驗 獲得超21個贊
您可以使用排列并給出長度。
from itertools import permutations
d = 16
n = 4
for item in permutations(range(d), r=n):
if sum(item) == d:
print("this is a suiting fit!", item)
我想你可能不需要排列
from itertools import product
d = 16
n = 4
for item in product(range(d), repeat=n):
if sum(item) == d:
print("this is a suiting fit!", item)
添加回答
舉報