Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 记忆使用Scipy Optmize的递归类实例_Python_Memoization - Fatal编程技术网

Python 记忆使用Scipy Optmize的递归类实例

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):

我使用的是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):
        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
    时,是否会将已计算的值添加到缓存中。无论我使用函数还是类,我仍然想知道答案。装饰师绝对可以。