Scipy.optimize - минимизировать не соблюдающие ограничения - PullRequest
0 голосов
/ 10 февраля 2020

Используя код ниже, чтобы понять, как работает оптимизация / минимизация Scipy. Результаты не соответствуют ожидаемым.

"""
Minimize: f = 2*x[0]*x[1] + 2*x[0] - x[0]**2 - 2*x[1]**2

Subject to: -2*x[0] + 2*x[1] <= -2
             2*x[0] - 4*x[1] <= 0
               x[0]**3 -x[1] == 0

where: 0 <= x[0] <= inf
       1 <= x[1] <= inf
"""
import numpy as np
from scipy.optimize import minimize

def objective(x):
    return 2.0*x[0]*x[1] + 2.0*x[0] - x[0]**2 - 2.0*x[1]**2

def constraint1(x):
    return +2.0*x[0] - 2.0*x[1] - 2.0

def constraint2(x):
    return -2.0*x[0] + 4.0*x[1] 

def constraint3(x):
    sum_eq = x[0]**3.0 -x[1]
    return sum_eq

# initial guesses
n = 2
x0 = np.zeros(n)
x0[0] =  10.0
x0[1] = 100.0

# show initial objective
print('Initial SSE Objective: ' + str(objective(x0)))

# optimize
#b = (1.0,None)
bnds = ((0.0,1000.0), (1.0,1000.0))
con1 = {'type': 'ineq', 'fun': constraint1} 
con2 = {'type': 'ineq', 'fun': constraint2} 
con3 = {'type': 'eq', 'fun': constraint3}
cons = ([con1, con2, con3])
solution = minimize(objective,
                    x0,
                    method='SLSQP',
                    bounds=bnds,
                    constraints=cons)
x = solution.x

print(solution)

# show final objective
print('Final SSE Objective: ' + str(objective(x)))

# print solution
print('Solution')
print('x1 = ' + str(x[0]))
print('x2 = ' + str(x[1]))
print('\n')
print('x', x)
print('constraint1', constraint1(x))
print('constraint2', constraint2(x))
print('constraint3', constraint3(x))

Когда я запускаю, Python выдает на своей консоли вывода:

Initial SSE Objective: -18080.0
     fun: 2.0
     jac: array([ 0.00000000e+00, -2.98023224e-08])
 message: 'Optimization terminated successfully.'
    nfev: 122
     nit: 17
    njev: 13
  status: 0
 success: True
       x: array([2., 1.])
Final SSE Objective: 2.0
Solution
x1 = 2.0000000000010196
x2 = 1.0000000000012386


x [2. 1.]
constraint1 -4.3787196091216174e-13
constraint2  2.915001573455811e-12
constraint3 7.000000000010997

Несмотря на то, что оптимизатор говорит, что результат был успешным, ограничение 3 не соблюдается, потому что результат должен быть нулевым. Чего мне не хватает?

1 Ответ

1 голос
/ 11 февраля 2020

Ваша проблема несовместима. Вы можете устранить 3-е ограничение (которое в первую очередь упрощает вашу задачу - только скалярную оптимизацию), после этого немного яснее понять, в чем проблема. Из ограничения 3 и нижней границы оригинала x1 следует, что x0 неосуществимо от 0 до 1, поэтому нижняя граница в одномерной задаче должна быть равна 1. Это легко видеть, что ограничение 2 всегда будет положительным, когда x0 больше 1, поэтому оно никогда не будет выполнено.

Когда я запускаю исходную задачу для меня, она останавливается с положительной производной по направлению (и для переписанной задачи с «Несовместимые ограничения неравенства»). Какой SciPy вы используете? Для меня это 1.4.1.

На рисунке ниже вы можете увидеть цель и оставшиеся ограничения для задачи 1D (горизонтальная ось - исходная x0 переменная)

enter image description here "" "Свернуть: f = 2 * x [0] * x 1 + 2 * x [0] - x [0] ** 2 - 2 * х 1 ** 2

Subject to: -2*x[0] + 2*x[1] <= -2
             2*x[0] - 4*x[1] <= 0
               x[0]**3 -x[1] == 0

where: 0 <= x[0] <= inf
       1 <= x[1] <= inf
"""
import numpy as np
from scipy.optimize import minimize

def objective(x):
    return 2*x**4 + 2*x - x**2 - 2*x**6

def constraint1(x):
    return x - x**3 - 1

def constraint2(x):
    return 2 * x**3 - x
#
# def constraint3(x):
#     sum_eq = x[0]**3.0 -x[1]
#     return sum_eq

# initial guesses
n = 1
x0 = np.zeros(n)
x0[0] =  2.
# x0[1] = 100.0

# show initial objective
print('Initial SSE Objective: ' + str(objective(x0)))

# optimize
#b = (1.0,None)
bnds = ((1.0,1000.0),)
con1 = {'type': 'ineq', 'fun': constraint1}
con2 = {'type': 'ineq', 'fun': constraint2}
# con3 = {'type': 'eq', 'fun': constraint3}
cons = [
    # con1,
    con2,
    # con3,
        ]
solution = minimize(objective,
                    x0,
                    method='SLSQP',
                    bounds=bnds,
                    constraints=cons)
x = solution.x

print(solution)

# show final objective
print('Final SSE Objective: ' + str(objective(x)))

# print solution
print('Solution')
print('x1 = ' + str(x[0]))
# print('x2 = ' + str(x[1]))
print('\n')
print('x', x)
print('constraint1', constraint1(x))
print('constraint2', constraint2(x))
# print('constraint3', constraint3(x))

x_a = np.linspace(1, 2, 200)
f = objective(x_a)
c1 = constraint1(x_a)
c2 = constraint2(x_a)

import matplotlib.pyplot as plt

plt.figure()

plt.plot(x_a, f, label="f")
plt.plot(x_a, c1, label="c1")
plt.plot(x_a, c2, label="c2")
plt.legend()
plt.show()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...