aa1
aa1

Reputation: 803

How to convert recursive "divide and conquer" function to a dynamic programming function using decorators?

I am trying to write a decorator function which converts a pure recursive function with two arguments that uses a "divide and conquer" strategy to an equivalent but more efficient one using dynamic programming. Note: it is designated to decorate two input functions.

So I am trying to memoize the values but I am not sure how to correctly implement it in the form of a decorator? Also how can it decorate two input functions?

EDIT: This is what I have managed to do:

profile_results = {}
t = {}

 '''The profile function stores the following: the time taken by the function, the name of the function and the number of times it was called and stores these in the dictionary called *profile_results* '''

def profile(func):
    import time
    def wrapper(*args, **kwargs):
        wrapper.calls += 1
        name = func.__name__
        t1 = time.time()
        res = func(*args, **kwargs)
        t2 = time.time() - t1
        t = (t2)
        my_tuple = (t,wrapper.calls)
        profile_results[name] = my_tuple
        return res
    wrapper.calls = 0
    return wrapper

#the dynamic function is the more efficient one and it is a decorator
@profile
def dynamic(func):
    def wrapper(*args, **kwargs):
        if args in t:
            return t[args]
        else:
            res = func(*args, **kwargs)
            t[args] = res
            return res
    return wrapper

#regular recursive function
@dynamic
@profile
def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n-1)

This is what it prints out when I test it:

factorial(5)
print(t)
print (profile_results)

Output:

{(0,): 1, (1,): 1, (2,): 2, (3,): 6, (4,): 24, (5,): 120}
{'dynamic': (0.0, 1), 'factorial': (0.0, 6)}

The first output is correct but I am trying to profile it to see if the dynamic programming one is actually faster. However, it is showing the times as 0. Would I need to add a time.sleep() somewhere and where would I add it to correctly output the time (given that they are recursive functions)?

I am wondering if I am decorating it properly. I am trying to decorate the dynamic function which is a decorator as well. And I am trying to decorate the factorial function with both the dynamic and profile function.

Any help would be appreciated!

Upvotes: 1

Views: 369

Answers (1)

glenfant
glenfant

Reputation: 1328

There's already a memoize / cache decorator in the standard library : https://docs.python.org/3/library/functools.html#functools.lru_cache

Don't re-invent the wheel, but perhaps it is not suited to what you need.

Upvotes: 1

Related Questions