如何正确编写 scipy SLSQP 的约束

问题描述 投票:0回答:1

我正在尝试使用 SLSQP 方法编写带有约束的优化代码。但我无法理解它足以为约束编写正确的代码。

假设我们有一个函数 f,带有 p 参数,所有参数都具有相同的起始值 (0.1),

arg
是这些参数的数组:

arg = [.1] * p

这里我希望

sum(arg[2:])
小于1,并且
arg[i] > 0
用于优化。我如何编写
scipy.optimize.minimize
:

的约束/边界
from scipy.optimize import minimize

minimize( fun = f,
          x0  = arg,
          method = 'SLSQP',
          constraints = ?,
          bounds = ?
)
python constraints scipy-optimize
1个回答
1
投票

首先,您不能使用像 g(x) < 1 or x > 0 这样严格的不等式约束。相反,您可以通过 g(x) ≥ 1 - ε 和 x ≤ ε 对其进行建模,其中 ε 是一个足够小的正常数。此外,如果

args
是您的起点,即仅由 1 组成的向量,那么就没有约束,因为
sum(c)
不依赖于您的任何优化变量。我认为您想添加所有优化变量(前两个除外)的总和小于 1 的约束:

请注意,scipy 期望每个等式约束采用 g(x) = 0 的形式,每个不等式约束采用 g(x) ≥ 0 的形式。因此,您可以通过

定义第一个约束
def con_fun(x, eps = 1.0e-8):
    # np.sum(x[2:]) ≤ 1 - eps
    # (np.sum(x[2:]) - 1 + eps ≤ 0
    # 1 - eps - np.sum(x[2:]) ≥ 0
    return 1 - eps - np.sum(x[2:])

constrs = [{'type': 'ineq', 'fun': con_fun})

你的第二个约束是优化变量的简单界限,因此

eps = 1.0e-8
# 0 + eps <= x[i] < ∞
bounds = [(0 + eps, None) for _ in range(p)]

最后就可以调用minimize方法了:

minimize(your_obj_fun, x0=x0, method='SLSQP', constraints=constrs, bounds=bounds)
© www.soinside.com 2019 - 2024. All rights reserved.