[英]Python - Calculating total possibilities using recursion
我试图找到如何在 90 个盒子中放置 90 个苹果的全部可能性。 任何数量的苹果都可以放在一个盒子里(0 到 90 个苹果),但所有的苹果都必须放在盒子里。 我使用了递归,但完成计算花费了太多时间。 我只能用少量的苹果和盒子来测试我的代码。 任何人都可以帮助我降低代码的时间复杂度吗? 提前致谢。
import math
boxes = 3
apples = 3
def possibilities(apples, boxes):
if apples == 0:
return 1
if boxes == 0:
return 0
start_point = 0 if boxes > 1 else math.floor(apples/boxes)
p = 0
for n in range(start_point, apples+1):
p += possibilities(apples-n, boxes-1)
return p
t = possibilities(apples,boxes)
print(t)
在我看来,问题在于找到总和等于 90 的最多 90 个元素的排序列表的数量。
有一个与此非常接近的概念,我们称之为数字的分区。
例如,4 的分区是[4], [3, 1], [2, 2], [2, 1, 1], [1, 1, 1, 1]
。
经过一番研究,我发现这篇文章与您的问题有关。
正如在那里解释的那样,递归方法会导致大量的计算时间很长,但是......
一种更有效的方法是通过称为动态编程的方法。 这里我们计算一个函数 psum(n,k),它是具有最大分量 k 或更小的 n 分区的总数。 在任何给定的阶段,我们都会为某个固定 k 计算 psum(1,k)、psum(2,k)、psum(3,k)、...、psum(n,k) 的值。 给定这个包含 n 个值的向量,我们计算 k+1 的值如下:
psum(i,k+1) = psum(i,k) + p(i,k) 对于任何值 i
但是回想一下 p(i,k) = Σj p(ik,j) = psum(ik,k)
所以 psum(i,k+1) = psum(i,k) + psum(ik,k)
因此,稍加注意,我们可以重用值向量,并在滚动值中计算 psum(i,k) 的值,以获得连续更大的 k 值。 最后,我们有一个向量,其值为 psum(i,n)。 值 psum(n,n) 是期望值 p(n)。 作为额外的好处,我们看到我们同时计算了 p(1), p(2), ..., p(n) 的值。
基本上,如果您将中间值保留在列表中并使用文章中提供的循环,
psum(i,k+1) = psum(i,k) + psum(ik,k)
您可以使用以下功能:
def partitionp(n):
partpsum = [1] * (n + 1)
for i in range(2, n + 1):
for j in range(i, n + 1):
partpsum[j] += partpsum[j - i]
return partpsum[n]
在外部 for 循环的每次迭代中,列表partpsum
包含所有值 psum(1,k), psum(2,k), psum(3,k), ..., psum(n,k)。 在迭代结束时,您只需要返回 psum(n,n)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.