방금 파이썬을 시작했는데 메모 가 무엇인지 , 어떻게 사용 하는지 전혀 몰랐 습니다. 또한 간단한 예가 있습니까?
답변
Memoization은 효과적으로 메소드 입력을 기반으로 메소드 호출의 결과를 기억 ( “memoization”→ “memorandum”→ 기억해야 함) 한 다음 결과를 다시 계산하지 않고 기억 된 결과를 리턴합니다. 메소드 결과의 캐시로 생각할 수 있습니다. 자세한 내용은 알고리즘 소개 (3e), Cormen et al.
파이썬에서 메모를 사용하여 계승을 계산하는 간단한 예는 다음과 같습니다.
factorial_memo = {}
def factorial(k):
if k < 2: return 1
if k not in factorial_memo:
factorial_memo[k] = k * factorial(k-1)
return factorial_memo[k]
더 복잡해지고 메모 프로세스를 클래스로 캡슐화 할 수 있습니다.
class Memoize:
def __init__(self, f):
self.f = f
self.memo = {}
def __call__(self, *args):
if not args in self.memo:
self.memo[args] = self.f(*args)
#Warning: You may wish to do a deepcopy here if returning objects
return self.memo[args]
그때:
def factorial(k):
if k < 2: return 1
return k * factorial(k - 1)
factorial = Memoize(factorial)
파이썬 데코레이터 에는 ” 데코레이터 ” 라는 기능 이 추가되어 동일한 기능을 수행하기 위해 다음을 간단히 작성할 수 있습니다.
@Memoize
def factorial(k):
if k < 2: return 1
return k * factorial(k - 1)
파이썬 데코레이터 라이브러리 라는 유사한 장식이 memoized
약간 더 견고보다 Memoize
여기에 표시된 클래스를.
답변
Python 3.2의 새로운 기능은 functools.lru_cache
입니다. 기본적으로, 그것은 단지 128 개 가장 최근에 사용 된 통화를 캐시하지만 당신은을 설정할 수 있습니다 maxsize
위해 None
캐시가 만료되지 않도록해야 함을 나타냅니다 :
import functools
@functools.lru_cache(maxsize=None)
def fib(num):
if num < 2:
return num
else:
return fib(num-1) + fib(num-2)
이 기능 자체는 매우 느리므로 시도해보십시오 fib(36)
. 약 10 초 정도 기다려야합니다.
lru_cache
주석을 추가 하면 특정 값에 대해 함수가 최근에 호출 된 경우 해당 값을 다시 계산하지 않고 캐시 된 이전 결과를 사용합니다. 이 경우 코드 속도가 엄청나게 향상되는 반면 코드는 캐싱의 세부 사항으로 복잡하지 않습니다.
답변
다른 답변은 그것이 무엇인지 잘 다룹니다. 나는 그것을 반복하지 않습니다. 당신에게 도움이 될만한 몇 가지 요점.
일반적으로 메모는 무언가를 계산하고 값이 비싼 모든 함수에 적용 할 수있는 작업입니다. 이 때문에 종종 데코레이터 로 구현됩니다 . 구현은 간단하며 다음과 같습니다.
memoised_function = memoise(actual_function)
또는 데코레이터로 표현
@memoise
def actual_function(arg1, arg2):
#body
답변
메모 화는 값 비싼 계산 결과를 유지하고 캐시 된 결과를 지속적으로 다시 계산하지 않고 반환합니다.
예를 들면 다음과 같습니다.
def doSomeExpensiveCalculation(self, input):
if input not in self.cache:
<do expensive calculation>
self.cache[input] = result
return self.cache[input]
더 자세한 설명은 메모 에 대한 wikipedia 항목에서 찾을 수 있습니다 .
답변
hasattr
수공예를 원하는 사람들을 위해 내장 기능을 잊지 마십시오 . 이렇게하면 전역과 달리 함수 정의 내에 mem 캐시를 유지할 수 있습니다.
def fact(n):
if not hasattr(fact, 'mem'):
fact.mem = {1: 1}
if not n in fact.mem:
fact.mem[n] = n * fact(n - 1)
return fact.mem[n]
답변
나는 이것이 매우 유용하다는 것을 알았습니다.
def memoize(function):
from functools import wraps
memo = {}
@wraps(function)
def wrapper(*args):
if args in memo:
return memo[args]
else:
rv = function(*args)
memo[args] = rv
return rv
return wrapper
@memoize
def fibonacci(n):
if n < 2: return n
return fibonacci(n - 1) + fibonacci(n - 2)
fibonacci(25)
답변
메모 화는 기본적으로 재귀 알고리즘으로 수행 한 과거 작업의 결과를 저장하여 나중에 동일한 계산이 필요한 경우 재귀 트리를 통과 할 필요성을 줄입니다.
참조 http://scriptbucket.wordpress.com/2012/12/11/introduction-to-memoization/를
Python의 피보나치 메모 화 예제 :
fibcache = {}
def fib(num):
if num in fibcache:
return fibcache[num]
else:
fibcache[num] = num if num < 2 else fib(num-1) + fib(num-2)
return fibcache[num]