简体   繁体   English

Scipy最小化忽略约束

[英]Scipy minimize ignores constraint

I have the following code: 我有以下代码:

def constraint(params):
    if abs(params[0] - 15) < 2 and abs(params[1] + 10) < 2:
        return -1
    else:
        return 0

def f(params):
    x, z = params
    if abs(x - 15) < 2 and abs(z + 10) < 2:
        return -9999999

    return (x - 15) ** 2 + (z + 10) ** 2 * numpy.sqrt(numpy.abs(numpy.sin(x)))

# Last: 15.00024144, -9.99939634

result = optimize.minimize(f, (-15, -15),
                           bounds=((-15.01, 15.01,), (-15.01, 15.01,),),
                           method="SLSQP",
                           options={'maxiter': 1024 * 1024},
                           jac=False,
                           constraints={
                               'type': 'ineq',
                               'fun': constraint,
                           })

print(result)
print(f(result.x))

And it gives the following result: 它给出了以下结果:

fun: -9999999.0
     jac: array([0., 0.])
 message: 'Optimization terminated successfully.'
    nfev: 12
     nit: 7
    njev: 3
  status: 0
 success: True
       x: array([ 15.01      , -11.60831378])
-9999999

The given values [ 15.01, -11.60831378] should be dropped by the constraint (and they were: if I add more verbose logging, I see that constraint function returns -1 , but scipy ignores it. Why? 应该通过约束删除给定值[ 15.01, -11.60831378] (它们是:如果我添加更详细的日志记录,我看到constraint函数返回-1 ,但是scipy忽略它。为什么?

I'm pretty far from data science and maths, so I'm sorry for stupid mistakes if they are there. 我离数据科学和数学很远,所以如果他们在那里我很抱歉会有愚蠢的错误。

To help the algorithm find the right direction, you need to separate your constraints: 为了帮助算法找到正确的方向,您需要分离约束:

def f(params):
    print(params)
    x, z = params
    if abs(x - 15) < 2 and abs(z + 10) < 2:
        return -9999999

    return (x - 15) ** 2 + (z + 10) ** 2 * numpy.sqrt(numpy.abs(numpy.sin(x)))

# Last: 15.00024144, -9.99939634

result = optimize.minimize(f, (-15, -15),
                           bounds=((-15.01, 15.01,), (-15.01, 15.01,),),
                           method="SLSQP",
                           options={'disp':True, 'maxiter': 1024 * 1024},
                           jac=False,
                           constraints=({
                               'type': 'ineq',
                               'fun': lambda params : abs(params[0] - 15) -2,
                           },
                           {
                               'type': 'ineq',
                               'fun': lambda params : abs(params[1] + 10) -2,
                           },)
        )

print(result)
print(f(result.x))

Gives: 得到:

Optimization terminated successfully.    (Exit mode 0)
            Current function value: 6.5928117149596535
            Iterations: 6
            Function evaluations: 24
            Gradient evaluations: 6
     fun: 6.5928117149596535
     jac: array([-1.2001152,  2.5928117])
 message: 'Optimization terminated successfully.'
    nfev: 24
     nit: 6
    njev: 6
  status: 0
 success: True
       x: array([13., -8.])
[13. -8.]
6.5928117149596535

Bingo! 答对了!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM