Scipy最小化忽略约束

时间:2018-05-26 17:58:59

标签: python scipy minimization

我有以下代码:

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))

它给出了以下结果:

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

应该通过约束删除给定值[ 15.01, -11.60831378](它们是:如果我添加更详细的日志记录,我看到constraint函数返回-1,但scipy忽略它。为什么呢?

我离数据科学和数学很远,所以如果他们在那里我会感到愚蠢的错误。

1 个答案:

答案 0 :(得分:3)

为了帮助算法找到正确的方向,您需要分离约束:

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))

给出:

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

宾果!