Сципи минимизирует игнорирует ограничение - PullRequest
0 голосов
/ 26 мая 2018

У меня есть следующий код:

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, но Сципи игнорирует это. Почему?

Я довольно далек от науки о данных и математики, поэтому я 'извините за глупые ошибки, если они есть.

1 Ответ

0 голосов
/ 26 мая 2018

Чтобы помочь алгоритму найти правильное направление, вам необходимо разделить ограничения:

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

Бинго!

...