python 的记忆功能 lru_cache(),用于动态规划,

python 中若编写递归函数,为了减少计算时间,需要用到 memoize 或 memoized 功能,它们的作用是记忆函数每次运行的结果,这样当递归函数每次递归时,若已经计算过子函数,就直接从记忆中的结果获取,避免重复计算。

英文解释可以参见:
https://wiki.python.org/moin/PythonDecoratorLibrary#CA-7f0e99ea942ab4cfe29b3964877c22f84954f660_26

方法一:使用 memoized 类,代码较多

在使用这个功能时,一般在程序前面加个 memoized 的类(这个类可以直接复制别人写好的代码)就行,然后在定义递归函数时前面加上
@memoized

例如斐波那契函数,下面的例子中,没有使用 memoized 功能的计算时间为 41 秒,使用后计算时间为 0秒。

import time
import functools
import collections


class memoized(object):
   '''Decorator. Caches a function's return value each time it is called.
   If called later with the same arguments, the cached value is returned
   (not reevaluated).
   '''
   def __init__(self, func):
      self.func = func
      self.cache = {}
   def __call__(self, *args):
      if not isinstance(args, collections.Hashable):
         # uncacheable. a list, for instance.
         # better to not cache than blow up.
         return self.func(*args)
      if args in self.cache:
         return self.cache[args]
      else:
         value = self.func(*args)
         self.cache[args] = value
         return value
   def __repr__(self):
      '''Return the function's docstring.'''
      return self.func.__doc__
   def __get__(self, obj, objtype):
      '''Support instance methods.'''
      return functools.partial(self.__call__, obj)


def fib(n) :
    if n in (0, 1):
        return n
    return fib(n-1)+fib(n-2)

@ memoized
def fib2(n) :
    if n in (0, 1):
        return n
    return fib2(n-1)+fib2(n-2)

start = time.clock()
a = fib(40)
print(a)
end = time.clock()
cpu_time = end-start
print('cpu  time is %.3f' % cpu_time)
start = time.clock()
b = fib2(40)
print(b)
end = time.clock()
cpu_time = end-start
print('cpu  time after memoizing is %.3f' % cpu_time)

输出结果:
102334155
cpu time is 40.536
102334155
cpu time after memoizing is 0.000

方法二:使用 lru_cache(),代码更少

同样需要调用 functools 包,在定义递归函数时前面加上
@lru_cache()
括号里面可以添加数字,表示记忆的条目数量。默认数量是 128。
如果最大容量不知道多少,可以在括号里加参数 maxsixe=None

实际的算例测试时,我感觉比第一种方法快
示例:

import time
from functools import lru_cache


def fib(n) :
    if n in (0, 1):
        return n
    return fib(n-1)+fib(n-2)


@lru_cache(1000)
def fib3(n) :
    if n in (0, 1):
        return n
    return fib3(n-1)+fib3(n-2)

start = time.clock()
a = fib(40)
print(a)
end = time.clock()
cpu_time = end-start
print('cpu  time is %.3f' % cpu_time)
start = time.clock()
b = fib3(40)
print(b)
end = time.clock()
cpu_time = end-start
print('cpu  time after memoizing is %.3f' % cpu_time)

输出:
102334155
cpu time is 37.304
102334155
cpu time after memoizing is 0.000

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心态与习惯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值