使用SLSQP进行的Scipy优化忽略了约束

时间:2017-12-06 20:12:30

标签: python optimization scipy constraints

我想用scipy优化下面的公式,添加x [0] -x [1]>的约束。 0.在目标函数中打印此表达式时,它也会给出负值,而优化会成功终止。最终目标是最小化sqrt(0.1 * x [0] * x [1]),这是由于数学错误导致的。

import numpy as np
from scipy.optimize import minimize


def f(x):

    print x[0] - x[1]
    #return sqrt(0.1*x[0]*x[1])
    return 0.1*x[0]*x[1]

def ineq_constraint(x):

    return x[0] - x[1]


con = {'type': 'ineq', 'fun': ineq_constraint}
x0 = [1, 1]
res = minimize(f, x0, method='SLSQP', constraints=con)

print res

输出:

0.0
0.0
1.49011611938e-08
-1.49011611938e-08
0.0
0.0
1.49011611938e-08
-1.49011611938e-08
0.0
0.0
1.49011611938e-08
-1.49011611938e-08
4.65661176285e-10
4.65661176285e-10
1.53668223701e-08
-1.44355000176e-08
     fun: 1.7509862319755833e-18
     jac: array([  3.95812066e-10,   4.42378184e-10,   0.00000000e+00])
 message: 'Optimization terminated successfully.'
    nfev: 16
     nit: 4
    njev: 4
  status: 0
 success: True
       x: array([  4.42378184e-09,   3.95812066e-09])

1 个答案:

答案 0 :(得分:1)

在一般情况下,我们不知道您的整个任务,所有步骤都没有强制执行约束(如所观察到的那样)!在不更改优化器的情况下,没有多少工作要做。甚至找到合适的优化器也许并不容易。

对于您的情况,如果您的变量是非负的,它将起作用!如果那是你可以在你的其他任务中使用的东西,我们不知道。

现在有两种非负性的方法:

  • 不等式
  • 边界

使用边界,使用显式处理(据我所知),在优化过程中不会违反这些处理。

示例:

import numpy as np
from scipy.optimize import minimize
from math import sqrt

def f(x):
    print(x)
    return sqrt(0.1*x[0]*x[1])

def ineq_constraint(x):
    return x[0] - x[1]

con = {'type': 'ineq', 'fun': ineq_constraint}

x0 = [1, 1]
res = minimize(f, x0, method='SLSQP', constraints=con, bounds=[(0, None) for i in range(len(x0))])
print(res)

输出:

[1. 1.]
[1. 1.]
[1.00000001 1.        ]
[1.         1.00000001]
[0.84188612 0.84188612]
[0.84188612 0.84188612]
[0.84188613 0.84188612]
[0.84188612 0.84188613]
[0.05131671 0.05131669]
[0.05131671 0.05131669]
[0.05131672 0.05131669]
[0.05131671 0.0513167 ]
[0. 0.]
[0. 0.]
[1.49011612e-08 0.00000000e+00]
[0.00000000e+00 1.49011612e-08]
     fun: 0.0
     jac: array([0., 0.])
 message: 'Optimization terminated successfully.'
    nfev: 16
     nit: 4
    njev: 4
  status: 0
 success: True
       x: array([0., 0.])