这被认为是记忆吗?

时间:2011-03-22 02:58:48

标签: optimization naming memoization

在最近优化某些代码时,我们最终执行了我认为是“类型”的备忘录,但我不确定我们应该这样称呼它。下面的伪代码不是实际的算法(因为我们在应用程序中几乎不需要因子,并且发布所述代码是一种触发攻击)但它应该足以解释我的问题。这是原来的:

def factorial (n):
    if n == 1 return 1
    return n * factorial (n-1)

很简单,但是我们添加了固定点,因此可以避免大数字的大量计算,例如:

def factorial (n):
    if n == 1 return 1
    if n == 10 return 3628800
    if n == 20 return 2432902008176640000
    if n == 30 return 265252859812191058636308480000000
    if n == 40 return 815915283247897734345611269596115894272000000000
    # And so on.

    return n * factorial (n-1)

这当然意味着12!计算为12 * 11 * 3628800而不是效率较低的12 * 11 * 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1

但是我想知道我们是否应该调用此备忘录,因为它似乎被定义为记住过去的计算结果并使用它们。这更多是关于硬编码计算(不记住)和使用该信息。

这个过程是否有正确的名称,或者我们可以声称,memoisation不仅可以延伸到运行时完成的计算,还可以延伸到编译时完成的计算,甚至可以追溯到我开始编写之前在脑中完成的计算代码?

4 个答案:

答案 0 :(得分:4)

我称之为预先计算而不是记忆。你并不记得你在计算给定输入的最终答案的过程中所做的任何计算,而是预先计算特定输入的一些固定数量的答案。记住,因为我理解它实际上更类似于“缓存”一组结果,因为您计算它们以供以后重用。如果您要存储计算的每个值,以便以后不需要再次重新计算,那将是memoization。您的解决方案的不同之处在于,您从不存储程序中的任何“计算”结果,只存储已预先计算的固定点。如果您使用不同于预先计算的输入的输入重新使用该函数,则不必重新计算结果,只需重复使用它即可。

答案 1 :(得分:1)

无论您是否对结果进行了硬编码,这仍然是记忆,因为您已经计算了期望再次计算的结果。现在这可能以运行时或编译时的形式出现..但不管怎样,都是memoization。

答案 2 :(得分:1)

记忆在运行时完成。您正在编译时进行优化。所以,事实并非如此。

例如参见...... Wikipedia

或......

  
      
  1. 记忆化   “记忆化”这一术语是由唐纳德·米奇(Donald Michie,1968)创造的,指的是一个函数用于自动记住先前计算结果的过程。随着功能语言的兴起,这一想法近年来变得越来越流行;菲尔德和哈里森(1988)专门用了整整一章。基本思想是保留先前计算的输入/结果对的表。
  2.   

Peter Norvig 加州大学 (大胆是我的)

Link

答案 3 :(得分:0)

def memoisation(f):
    dct = {}
    def myfunction(x):
        if x not in dct:            
            dct[x] = f(x)
        return dct[x]
    return myfunction

@memoisation
def fibonacci(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fibonacci(n-1) + fibonacci(n-2)

def nb_appels(n):
    if n==0 or n==1:
        return 0
    else:
        return  1 + nb_appels(n-1) + 1 + nb_appels(n-2)


print(fibonacci(13))
print ('nbappel',nb_appels(13))