Python 在递归代码中断功能中实现记忆

Python 在递归代码中断功能中实现记忆,python,recursion,memoization,Python,Recursion,Memoization,我似乎不知道是什么破坏了我的密码 我写了一个以金字塔为单位的代码: [[1], [2,3], [4,5,6], [7,8,9,10]] 从头部开始(金字塔[0][0])通过递归移动到下面的项目或下面和右边的项目,计算可能达到的最大总和 在本例中,输出应为20 这是一段没有备忘录的代码,可以很好地工作: def max_trail(pyramid,row=0,col=0): if row == (len(pyramid)-1): return pyramid[row

我似乎不知道是什么破坏了我的密码

我写了一个以金字塔为单位的代码:

[[1],
 [2,3],
 [4,5,6],
 [7,8,9,10]]
从头部开始(金字塔[0][0])通过递归移动到下面的项目或下面和右边的项目,计算可能达到的最大总和

在本例中,输出应为20

这是一段没有备忘录的代码,可以很好地工作:

def max_trail(pyramid,row=0,col=0):
    if row == (len(pyramid)-1):
        return pyramid[row][col]
    else:
        return pyramid[row][col] + max(max_trail(pyramid ,row+1 ,col),
                                       max_trail(pyramid ,row+1, col+1))
但当我尝试运用记忆法时,一路上有些事情发生了。 我错过了什么

这是坏代码:

def max_trail_mem(pyramid,row=0,col=0,mem=None):
    if mem==None:
        mem={}
    key = ((row),(col))
    if row == (len(pyramid)-1):
        if key not in mem:
            value = pyramid[row][col]
            mem[key]=value
            return mem[key]
        return mem[key]
    else:
        key = (row+1),(col)
        if key not in mem:
            mem[(row+1),(col)] = max_trail_mem(pyramid ,row+1 ,col,mem)
        key = (row+1),(col+1)
        if key not in mem:
            mem[(row+1),(col+1)]=max_trail_mem(pyramid ,row+1, col+1,mem)
    return max(mem[(row+1),(col)],mem[(row+1),(col+1)])
这使我可怜的学习生活少了几个小时。
任何帮助都将不胜感激

您在上次返回时忘记了
max(…
之前的
pyramid[row][col]+
。添加它将为您的示例提供
20
(请参见最后一行代码):

返回:

without memoization:   3.9645819664001465
with memoization:      0.18628692626953125

欢迎使用StackOverflow!请花点时间阅读并查看。在编写时,您的问题是询问调试帮助“为什么此代码不工作?”这在as offtopic for stackoverflow中有明确的概述。您是否尝试过在失败的地方进行测试?您可以添加打印语句以进行快速测试或使用。谢谢!这很有效!但是…似乎这里的备忘录并没有改善运行时间…它有任何贡献吗?我尝试了一个10号金字塔,它返回了sa我在没有回忆录的版本中运行时间,有什么建议吗?回忆录版本的运行时间是41.2µs,纯递归版本的运行时间是201µs。因此,对于大小为10的金字塔,速度大约快5倍。对于大小为15的金字塔,差异是101µs和6.15 ms,即超过60的系数。对于大小为20的金字塔,这个系数超过1000。谢谢哎哟,迈克,我试过一个更大的金字塔,它确实有用!
from timeit import timeit
import math

from repoze.lru import CacheMaker
cache_maker=CacheMaker()


def max_trail(pyramid,row=0,col=0):
    if row == (len(pyramid)-1):
        return pyramid[row][col]
    else:

        mt1 = max_trail(pyramid ,row+1 ,col)
        mt2 = max_trail(pyramid ,row+1, col+1)
        return pyramid[row][col] + max(mt1, mt2)

@cache_maker.lrucache(maxsize='1000', name='pyramid')
def max_trail_with_memoization(pyramid,row=0,col=0):
    if row == (len(pyramid)-1):
        return pyramid[row][col]
    else:

        mt1 = max_trail(pyramid ,row+1 ,col)
        mt2 = max_trail(pyramid ,row+1, col+1)
        return pyramid[row][col] + max(mt1, mt2)

# Build pyramid
pyramid = ()
c = 0
for i in range(20):
    row = ()
    for j in range(i):
        c += 1
        row += (c,)
    if row:
        pyramid += (tuple(row),)

# Repetitions to time
number = 20

# Time it
print('without memoization:  ', timeit('f(t)', 'from __main__ import max_trail as f, pyramid as t', number=number))
print('with memoization      ', timeit('f(t)', 'from __main__ import max_trail_with_memoization as f, pyramid as t', number=number))




print max_trail(pyramid)
without memoization:   3.9645819664001465
with memoization:      0.18628692626953125