Python Scipy最小化忽略约束

Python Scipy最小化忽略约束,python,scipy,minimization,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

我有以下代码:

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))
给定的值
[15.01,-11.60831378]
应该被约束删除(它们是:如果我添加更多详细的日志记录,我看到
约束
函数返回
-1
,但scipy忽略了它。为什么


我远离数据科学和数学,因此如果存在愚蠢的错误,我很抱歉。

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

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

答对了!

@arts777我意识到约束中有一个输入错误,您实际上可以使用原始的
f
函数得到结果,但Yakim有一点说,将较大的正值作为默认值更明智。
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