Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 整数划分的递归公式_Python_Recursion - Fatal编程技术网

Python 整数划分的递归公式

Python 整数划分的递归公式,python,recursion,Python,Recursion,我编写了以下代码,用于使用涉及五边形数的递归公式计算整数分区: def part(n): p = 0 if n == 0: p += 1 else: k = 1 while ((n >= (k*(3*k-1)/2)) or (n >= (k*(3*k+1)/2))): i = (k * (3*k-1)/2) j = (k * (3*k+1)/2)

我编写了以下代码,用于使用涉及五边形数的递归公式计算整数分区:

def part(n):
    p = 0
    if n == 0:
        p += 1
    else:
        k = 1
        while ((n >= (k*(3*k-1)/2)) or (n >= (k*(3*k+1)/2))):
            i = (k * (3*k-1)/2)
            j = (k * (3*k+1)/2)
            if ((n-i) >= 0):
                p -= ((-1)**k) * part(n-i)
            if ((n-j) >= 0):
                p -= ((-1)**k) * part(n-j)
            k += 1
    return p

    n = int(raw_input("Enter a number: "))
    m = part(n)
    print m
代码在
n=29
之前工作正常。它在
n=24
附近变得有点慢,但我仍然在一个合适的运行时间内得到了输出。我知道算法是正确的,因为生成的数字与已知值一致

对于35以上的数字,即使等待了很长时间(大约30分钟),我也没有得到输出。我的印象是python可以处理比这里使用的数字大得多的数字。有人能帮我改进我的运行时间并获得更好的结果吗?另外,如果代码有问题,请告诉我

您可以使用:

演示:


通过记忆,我们可以记住之前的计算,因此对于重复的计算,我们只需在字典中查找即可。

嗯,您可以做很多事情

  • 删除重复的计算。-基本上,对于while循环的每次执行,您都要多次计算“3*k+1”。您应该计算一次并将其分配给变量,然后使用该变量

  • 将(-1)**k替换为一个更快的操作,比如-2*(k%2)+1)。所以它不是关于k的线性计算,而是常数

  • 缓存昂贵的确定性计算结果。“部分”是一个确定性函数。使用相同的参数多次调用它。您可以构建映射到结果的输入的hashmap

  • 考虑重构它以使用循环而不是递归。据我所知,Python不支持尾部递归,因此在使用深度递归时,它必须维护非常大的堆栈


  • 如果你缓存计算,我可以保证它的运行速度会快很多倍

    对于n=500,我得到一个运行时错误,表示超过了最大递归深度。有什么办法可以解决这个问题吗?@Nannu,你可以增加递归限制,但实际上你最好是迭代实现它。Python没有针对递归进行优化我可以达到n=999,之后的任何事情都会让我大吃一惊我知道递归并不是Python中最好的方法,但我想使用递归获得答案;我有另一个不使用递归的公式,所以我想比较一下。你能解释一下如何增加递归限制吗?是的,在得到错误之前,我得到了n=500。这是在记忆了函数之后,我认为缓存优化从我的回答中非常明显,迭代解决方案可能是真正改进OP自身代码的唯一方法caching@Adam,我知道递归并不是python中最好的方法,但我想用递归得到答案;我有另一个不使用递归的公式,所以我想比较一下。
    def memo(f):
        mem = {}
        def wrap(x):
            if x not in mem:
                mem[x] = f(x)
            return mem[x]
        return wrap
    
    @memo
    def part(n):
        p = 0
        if n == 0:
            p += 1
        else:
            k = 1
            while (n >= (k * (3 * k - 1) // 2)) or (n >= (k * (3 * k + 1) // 2)):
                i = (k * (3 * k - 1) // 2)
                j = (k * (3 * k + 1) // 2)
                if (n - i) >= 0:
                    p -= ((-1) ** k) * part(n - i)
                if (n - j) >= 0:
                    p -= ((-1) ** k) * part(n - j)
                k += 1
        return p
    
    In [9]: part(10)
    Out[9]: 42
    
    In [10]: part(20)
    Out[10]: 627
    
    In [11]: part(29)
    Out[11]: 4565
    
    In [12]: part(100)
    Out[12]: 190569292