我正在尝试使用 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 = ?
)
首先,您不能使用像 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)