如何转换递归"划分和征服"使用装饰器的动态编程功能?

时间:2017-12-17 03:49:26

标签: python profiling dynamic-programming decorator

我正在尝试编写一个装饰器函数,该函数使用两个参数转换纯递归函数,这两个参数使用"分而治之而且#34;使用动态编程的等效但更有效的策略。 注意:它被指定用于装饰两个输入函数。

所以我试图记住这些值,但我不确定如何以装饰器的形式正确实现它?另外它如何装饰两个输入函数?

编辑: 这就是我设法做的事情:

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)

这是我测试时打印出的内容:

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

输出:

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

第一个输出是正确的,但我试图对其进行分析,以查看动态编程实际上是否更快。但是,它将时间显示为0.我是否需要在某处添加 time.sleep()以及在哪里添加它以正确输出时间(假设它们是递归函数)?< / p>

我想知道我是否正确装饰它。我正在尝试装饰动态函数,它也是一个装饰器。我试图用动态和轮廓函数来装饰阶乘函数。

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

标准库中已经有一个memoize / cache装饰器:https://docs.python.org/3/library/functools.html#functools.lru_cache

不要重新发明轮子,但也许它不适合你需要的东西。