【发布时间】:2019-03-06 17:44:19
【问题描述】:
我正在使用 Python 2.7,并且有一个解决递归优化问题,即动态规划问题的程序。代码的简化版本是:
from math import log
from scipy.optimize import minimize_scalar
class vT(object):
def __init__(self,c):
self.c = c
def x(self,w):
return w
def __call__(self,w):
return self.c*log(self.x(w))
class vt(object):
def __init__(self,c,vN):
self.c = c
self.vN = vN
def objFunc(self,x,w):
return -self.c*log(x) - self.vN(w - x)
def x(self,w):
x_star = minimize_scalar(self.objFunc,args=(w,),method='bounded',
bounds=(1e-10,w-1e-10)).x
return x_star
def __call__(self,w):
return self.c*log(self.x(w)) + self.vN(w - self.x(w))
p3 = vT(2.0)
p2 = vt(2.0,p3)
p1 = vt(2.0,p2)
w1 = 3.0
x1 = p1.x(w1)
w2 = w1 - x1
x2 = p2.x(w2)
w3 = w2 - x2
x3 = w3
x = [x1,x2,x3]
print('Optimal x when w1 = 3 is ' + str(x))
如果添加了足够多的时间段,程序可能会开始需要很长时间才能运行。当x1 = p1.x(w1) 运行时,p2 和p3 将被minimize_scalar 多次评估。此外,当运行x2 = p2(w2) 时,我们知道最终的解决方案将涉及以第一步中已经完成的方式评估p2 和p3。
我有两个问题:
- 在
vT和vt类上使用 memoize 包装器来加速这个程序的最佳方法是什么? - 当
minimize_scalar运行时,它会从这种记忆中受益吗?
在我的实际应用中,解决方案目前可能需要数小时才能解决。因此,加快这一进程将非常有价值。
更新:下面的回应指出,上面的例子可以不使用类来编写,普通的装饰可以用于函数。在我的实际应用程序中,我必须使用类,而不是函数。此外,我的第一个问题是 minimize_scalar 内部的函数或方法的调用(当它是一个类时)是否会受益于记忆化。
【问题讨论】:
-
这些不需要是类。 One of the hallmarks of not being a class is that it has two functions, one of which is
__init__. 记忆返回值是标准的example of decorators(或SO answer implementing it)。如果您希望避免在整个代码中重复c的值,请考虑使用functools.partial函数。判断记忆是否有帮助的最好方法是对其进行分析;显然,记住很多结果会消耗更多的内存。 -
@jpmc26 我试图简化我的实际代码,以隔离与记忆和
minimize_scalar命令相关的问题。我使用的实际类每个都有几百行代码,甚至这里的这些类也有两个以上的功能。我的示例中的那些可能被重写为只有两个函数,但不是我实际应用程序中的那些。在这种情况下,您提供的链接与课程无关。如果我确实必须使用类,我会怎么做。如果您认为有必要,我可以粘贴我的实际代码(2000 多行)。 -
@jpmc26 另一个问题是,当我使用
minimize_scalar时,memoized 函数的调用是否会添加到已经计算过的值的缓存中。无论我使用函数还是类,我仍然想知道答案。 -
装饰者绝对可以be applied to instance methods.
标签: python memoization