Python 记忆使用Scipy Optmize的递归类实例
我使用的是Python2.7,有一个程序可以解决递归优化问题,也就是动态编程问题。代码的简化版本为:Python 记忆使用Scipy Optmize的递归类实例,python,memoization,Python,Memoization,我使用的是Python2.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):
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\u scalar
时,它是否会从这种记忆中受益更新:下面的一个回复指出,上面的示例可以不使用类而编写,并且正常的修饰可以用于函数。在我的实际应用程序中,我必须使用类,而不是函数。此外,我的第一个问题是
minimize\u scalar
中函数或方法的调用(当它是类时)是否会从记忆中受益。我找到了答案。下面是一个如何记忆程序的示例。可能有一种更有效的方法,但这种方法会记住类的方法。此外,当运行minimize\u scalar
时,memoize包装器会在每次评估函数时记录结果:
from math import log
from scipy.optimize import minimize_scalar
from functools import wraps
def memoize(obj):
cache = obj.cache = {}
@wraps(obj)
def memoizer(*args, **kwargs):
key = str(args) + str(kwargs)
if key not in cache:
cache[key] = obj(*args, **kwargs)
return cache[key]
return memoizer
class vT(object):
def __init__(self,c):
self.c = c
@memoize
def x(self,w):
return w
@memoize
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
@memoize
def objFunc(self,x,w):
return -self.c*log(x) - self.vN(w - x)
@memoize
def x(self,w):
x_star = minimize_scalar(self.objFunc,args=(w,),method='bounded',
bounds=(1e-10,w-1e-10)).x
return x_star
@memoize
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)
x1 = p1.x(3.0)
len(p3.x.cache) # how many times was p3.x evaluated?
Out[3]:60
x2 = p2.x(3.0 - x1)
len(p3.x.cache) # how many additional times was p3.x evaluated?
Out[5]:60这些不需要是类。记忆返回值是一种标准。如果您希望避免在代码中重复<代码> C <代码>的值,请考虑<代码>功能工具。判断记忆是否有帮助的最好方法是描述它;显然,记忆许多结果会消耗更多内存。@jpmc26我试图简化实际代码,以隔离与记忆和
minimize_scalar
命令相关的问题。我使用的实际类每个都有几百行代码,甚至这里的这些类也有两个以上的函数。我的示例中的函数可能被重写为只有两个函数,但实际应用程序中的函数可能没有。在这种情况下,您提供的链接不属于类。如果我确实必须使用类,我该怎么办。如果您认为有必要,我可以粘贴我的实际代码(2000多行)。@jpmc26另一个问题是,当我使用minimize\u scalar
时,是否会将已计算的值添加到缓存中。无论我使用函数还是类,我仍然想知道答案。装饰师绝对可以。