Scipy 最小化:如何将参数传递给目标和约束

Posted

技术标签:

【中文标题】Scipy 最小化:如何将参数传递给目标和约束【英文标题】:Scipy minimize: How to pass args to both the objective and the constraint 【发布时间】:2019-07-03 20:05:12 【问题描述】:

我的MWE如下

def obj(e, p):
    S = f(e) + g(p)
    return S

我想仅通过 e 最小化这个函数,并将 p 作为参数传递给函数。但是,我也想要一个依赖于 pe 的约束,其形式为 p + e < 1

我试过了

cons = 'type': 'ineq',
       'fun': lambda e, p: -e -p + 1,
       'args': (p)

然后,我尝试将 p = 0.5 的情况最小化

minimize(obj, initial_guess, method = 'SLSQP', args = 0.5, constraints = cons)

但这不起作用。我在定义cons 的行中收到错误name 'p' is not defined。如何将参数 p 传递给目标函数和约束?


完整代码如下

from scipy.optimize import minimize
from scipy.stats import entropy
import numpy as np

#Create a probability vector
def p_vector(x):
    v = np.array([x, 1-x])
    return v


#Write the objective function 
def obj(e, p):
    S = -1*entropy(p_vector(p + e), base = 2) 
    return S

##Constraints
cons = 'type': 'ineq',
       'fun': lambda e: -p - e + 1,
       'args': (p,)
       

initial_guess = 0

result = minimize(obj, initial_guess, method = 'SLSQP', args = (0.5, ), constraints = cons)
print(result)

【问题讨论】:

args 作为元组传递使用(p,)(0.5,)。在某些情况下,它可能会为您将标量变成元组,但为了安全起见,我自己会这样做。 我在定义 cons 时使用 'args': (p,) 进行了尝试,但我仍然有一个错误,提示名称 'p' 未在该行中定义。另外,如果不清楚 p = 0.5 是我正在尝试运行的情况 args=(0.5,) 在对obj 的调用中设置p。但是查看minimize 文档,它看起来像cons 中的args,定义了传递给lambda 的内容。所以我会尝试'args': (0.5,)。我没有经常使用cons,所以我完全根据文档工作,而不是经验。 嗯,它现在给了我一个新错误“() 需要 1 个位置参数,但给出了 2 个”。为了清楚起见,我已将完整代码附加到问题中 【参考方案1】:

好的,我认为这是我的语法错误以及应如何传递参数的混合。对于可能有相同问题的人,我将在此处发布答案。

目标函数是obj(e, p)。我们只想最小化e,所以我们创建了一个包含其他参数arguments = (0.5,) 的元组。也就是说,设置了一个特定的值p=0.5。接下来定义约束函数

def prob_bound(e, p):
    return -e - p + 1

现在将约束字典写成

cons = ('type': 'ineq',
       'fun': prob_bound,
       'args': arguments       
       )

最后,调用最小化器

result = minimize(obj, initial_guess, method = 'SLSQP', args = arguments, constraints = cons)

【讨论】:

以上是关于Scipy 最小化:如何将参数传递给目标和约束的主要内容,如果未能解决你的问题,请参考以下文章

如何将参数传递给其他函数(通常通过 scipy)?

如何在使用 LowLevelCallable cfunc 时使用 scipy.integrate.nquad 并将参数传递给它

如何将 NSData 参数传递给在 swift 3 中调用的目标 c 方法?

如何将参数传递给 sql 'in' 语句?

如何将参数传递给 Java 线程?

如何将参数传递给批处理文件[重复]