如何正确编写scipy SLSQP的约束条件

huangapple go评论67阅读模式
英文:

How to write the constraints for scipy SLSQP properly

问题

You can set up the constraints and boundaries for your optimization problem in the minimize function as follows:

from scipy.optimize import minimize

# Define your constraints
def constraint1(arg):
    return sum(arg[2:]) - 1

def constraint2(arg):
    return arg  # This enforces arg[i] > 0 for all i

constraints = ({'type': 'ineq', 'fun': constraint1},
               {'type': 'ineq', 'fun': constraint2})

# Define your parameter bounds
bounds = [(0, None)] * p  # This sets arg[i] to be greater than or equal to 0 for all i

# Call minimize with constraints and bounds
result = minimize(fun=f, x0=arg, method='SLSQP', constraints=constraints, bounds=bounds)

This code sets up two constraints: one for the sum of arg[2:] to be less than 1 and another to ensure that each arg[i] is greater than or equal to 0. The bounds variable is used to specify that all parameters should be greater than or equal to 0.

You can then call minimize with these constraints and bounds to optimize your function f using the SLSQP method.

英文:

I am trying to write an optimization code with constraints using SLSQP method. But I can't understand it enough to write the proper codes for constraints.

Lets say we have a function f, with p parameters, all with the same starting values (0.1) and arg is the array of these parameters:

arg = [.1] * p

Here I want sum(arg[2:]) to be less than 1, and arg[i] > 0 for the optimization. How can i write the constraints/boundaries for scipy.optimize.minimize:

from scipy.optimize import minimize

minimize( fun = f,
          x0  = arg,
          method = 'SLSQP',
          constraints = ?,
          bounds = ?
)

答案1

得分: 2

以下是翻译好的部分:

首先,你不能使用严格的不等式约束,如 g(x) < 1 或 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)
英文:

First of all, you can't use strict inequality constraints like g(x) < 1 or x > 0. Instead, you can model them by g(x) ≥ 1 - ε and x ≤ ε, where ε is a sufficiently small positive constant. In addition, if args is your starting point, i.e. the vector consisting of 1s only, then there's no constraint as sum(c) doesn't depend on your any optimization variable. I take it you'd like to add the constraint that the sum of all the optimization variables (except the first two ones) is smaller than 1:

Note that scipy expects each equality constraint in the form g(x) = 0 and each inequality constraint in the form g(x) ≥ 0. Therefore, you can define your first constraint by

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 = [{&#39;type&#39;: &#39;ineq&#39;, &#39;fun&#39;: con_fun})

Your second constraints are simple bounds on the optimization variables, thus

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

Finally, you can can call the minimize method:

minimize(your_obj_fun, x0=x0, method=&#39;SLSQP&#39;, constraints=constrs, bounds=bounds)

huangapple
  • 本文由 发表于 2023年5月15日 03:19:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76249292.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定