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

邮差的信 提交于 2020-01-16 18:53:13

问题


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!


回答1:


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.



来源:https://stackoverflow.com/questions/47852041/how-to-convert-recursive-divide-and-conquer-function-to-a-dynamic-programming

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!