动态编程是一种可用于对纯递归进行优化的方法。只要我们看到递归解决方案重复调用相同的输入,就可以使用动态编程对其进行优化。这样做的想法是简单地存储子问题的结果,这样我们就不必在以后需要时重新计算它们。这种简单的优化降低了从指数到多项式的时间复杂度。在本文中,已经讨论了使用Python词典实现动态编程的方法。
为了理解Python动态编程的实现,让我们使用Fibonacci数问题对其进行可视化。
用数学术语来说,斐波纳契数的序列由递归关系定义:
Fn = Fn-1 + Fn-2
具有种子值:
F0 = 0 and F1 = 1
例子:
Input: N = 9
Output: 34
Explanation:
9th number in the Fibonacci series is 34.
Input: N = 2
Output: 1
Explanation:
2nd number in the Fibonacci series is 1.
下面是幼稚方法的实现:
# Function to find nth Fibonacci number
def Fibonacci(n):
# Corner case
if n<0:
print("Incorrect input")
# Base case
elif n == 0:
return 0
elif n == 1:
return 1
# Recursive case
else:
return Fibonacci(n-1)+Fibonacci(n-2)
print(Fibonacci(9))
34
显然,上述方法具有指数时间复杂度。为了存储先前计算的结果,让我们使用Python的字典类。
方法:想法是自定义字典类的__missing__方法。当用户尝试访问不在词典中的键时,将执行此方法。我们将使用自己的函数定义来重写此方法。
下面是上述方法的实现:
# Python program to customize the
# __missing__ method of the
# dictionary class in python
class Fibonacci(dict):
# Function signature of the
# __missing__ function in
# python
def __missing__(self, n):
# Base case
if n<= 1:
# Storing the value in the
# dictionary before returning
self[n] = n
return n
# Storing the value in the dictionary
# before returning the value
val = self[n] = self[n-1] + self[n-2]
return val
if __name__ == "__main__":
# Create an instance of the class
Fib = Fibonacci()
N = Fib[9]
print(N)
34
上述方法也可以通过在Python使用装饰器来实现。
Decorator是Python一个非常强大且有用的工具,因为它允许程序员修改函数或类的行为。装饰器允许我们包装另一个函数,以扩展被包装函数的行为,而无需对其进行永久性修改。在这里,备忘录用于实现装饰器。
下面是上述方法的实现:
# Python program to find the nth Fibonacci
# number with memoization using decorators
from inspect import signature
# Defining a decorator
class memoise(dict):
# Initializing function
def __init__(self, func):
self.func = func
self.signature = signature(func)
# Missing method to store the
# Fibonacci numbers in a
# Dictionary
def __missing__(self, key):
(arg, kwarg) = key
self[key] = val = self.func(*arg,
**dict(kwarg))
return val
def __call__(self, *arg, **kwarg):
key = self.signature.bind(*arg,
**kwarg)
return self[key.args,
frozenset(key.kwargs.items())]
# Function to find the n-th Fibonacci
# number using the above defined
# decorator
@memoise
def Fibonacci(n):
# Corner case
if n<0:
print("Incorrect input")
# Base cases
elif n == 0:
return 0
elif n == 1:
return 1
# Recursive case
else:
return Fibonacci(n-1)+Fibonacci(n-2)
if __name__ == "__main__":
print(Fibonacci(9))
34