Skip to content
Related Articles

Related Articles

Improve Article
Python | Implementing Dynamic programming using Dictionary
  • Last Updated : 22 May, 2020

Dynamic Programming is one way which can be used as an optimization over plain recursion. Wherever we see a recursive solution that has repeated calls for the same inputs, we can optimize it using Dynamic Programming. The idea is to simply store the results of subproblems so that we do not have to re-compute them when needed later. This simple optimization reduces time complexities from exponential to polynomial. In this article, a method to use dictionaries of python to implement dynamic programming has been discussed.

In order to understand the implementation of the dynamic programming in python, lets visualize it using the Fibonacci numbers problem.

In mathematical terms, the sequence of Fibonacci numbers is defined by the recurrence relation:

Fn = Fn-1 + Fn-2

with seed values:

F0 = 0 and F1 = 1

Examples:



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.

Below is the implementation of the naive approach:




# 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)) 
Output:
34

Clearly, the above approach has exponential time complexity. In order to store the previously computed results, let us use the dictionary class of python.

Approach: The idea is to customize the __missing__ method of the dictionary class. This method is executed when the user tries to access a key which is not in the dictionary. We will use our own function definition to rewrite this method.

Below is the implementation of the above approach:




# 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
  
        # 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)
Output:
34

The above method can also be implemented by using a decorator in python.

Decorator is a very powerful and useful tool in python since it allows programmers to modify the behaviour of function or class. Decorators allow us to wrap another function in order to extend the behaviour of the wrapped function, without permanently modifying it. Here, memoization is used to implement a decorator.

Below is the implementation of the above approach:




# 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)) 
Output:
34

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with industry experts, please refer DSA Live Classes




My Personal Notes arrow_drop_up
Recommended Articles
Page :