python - scipy.optimize.minimize_scalar() 在目标函数内向辅助函数结果添加约束?

标签 python scipy scipy-optimize scipy-optimize-minimize

我有一个函数 func_x(),我试图使用 scipy.optimize.minimize_scalar() 最小化它。

func_x() 还调用另一个函数 func_y(),其结果 func_x() 部分用于计算最终标量值。我希望优化对 func_y() 的值也有约束,例如 func_y() 结果的最小值或最大值。在我 future 的情况下,可能还会有其他辅助函数,但共同点是,给定标量输入 x,它们还将返回一个标量值供 func_x() 使用。

from scipy.optimize import minimize_scalar
def func_y(x):
    return x^2-1/x
def func_x(x):
    return (x - 2) * func_y(x) * (x + 2)**2

res = minimize_scalar(func_x, bounds=(-10, 10), method='bounded')
res.x

是否有办法在 scipy.optimize 中强制执行类似 func_y(x) > 1 的约束。最小化标量()?

我检查了文档 - 我相信bounds参数仅设置标量输入x的优化下限/上限。

根据用户 ekrall 的建议,我还研究了 scipy.optimize.minimize() 以及约束参数的使用

from scipy.optimize import minimize

def constraint1(x):
    return func_y(x)-1

con1 = {'type': 'ineq', 'fun': constraint1}


应该检查 func_y(x) >= 1

最佳答案

我还建议您使用minimize 。 您只需要了解限制

Constraints definition (only for COBYLA, SLSQP and trust-constr).

还有

Note that COBYLA only supports inequality constraints.

由此我们得出结论,必须选择 SLSQPtrust-constr

使用trust-constr,结果很好

res = minimize(func_x, 5, method='SLSQP', bounds=[[-10, 10]], 
               constraints=[{'type': 'ineq', 'fun': lambda x: 1-func_y(x)}])
print(res.x, res.fun, func_y(res.x), res.success)
res = minimize(func_x, 5, method='SLSQP', bounds=[[-10, 10]], 
               constraints=[{'type': 'ineq', 'fun': lambda x: func_y(x)-1}])
print(res.x, res.fun, func_y(res.x), res.success)
res = minimize(func_x, 5, method='SLSQP', bounds=[[-10, 10]])
print(res.x, res.fun, func_y(res.x), res.success)

给出

[1.32467216] [-7.4635986] [0.99985257]
[1.59008719] [-10.0354401] [1.89948096]
[1.59008719] [-10.0354401] [1.89948093]

但是,这种类型约束对于 SLSQP 无法正常工作。

表示约束的另一种方法是 NonlinearConstraintLinearConstraint ,在这种情况下 SLSQP 工作正常

res = minimize(func_x, 5, method='trust-constr', bounds=[[-10, 10]], 
               constraints=[NonlinearConstraint(func_y, lb=1, ub=1.5)])
print(res.x, res.fun, func_y(res.x))
res = minimize(func_x, 5, method='SLSQP', bounds=[[-10, 10]], 
               constraints=[NonlinearConstraint(func_y, lb=1, ub=1.5)])
print(res.x, res.fun, func_y(res.x))

给出

[1.47559988] [-9.50009675] [1.49970451]
[1.47568652] [-9.50087235] [1.5]

一个重要的细节是约束 func_y(x) > 1 将您的域分为两部分,目标函数在左侧更好,但该方法可能只会探索左侧的部分对。

enter image description here

关于python - scipy.optimize.minimize_scalar() 在目标函数内向辅助函数结果添加约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70705656/

相关文章:

python - 从数据框中删除顶行

python - 如何在 Django FloatField 中放入无穷大和负无穷大?

python线程和性能?

python - 有人可以解释一下 np.log 是做什么的吗?

python - 具有指定范围的最近邻一维数据

python - 在 Python 中求解 6 个非线性方程组时出现问题

python - curve_fit似乎高估了估计参数的误差

python - 根据算法或模式重新排序 python 列表

python - 通过 scipy 拟合函数传递 numpy 数组

python - 在 Theano 中定义一个带循环的函数