SciPy SLSQP утверждает, что ограничения несовместимы, когда ограничения совместимы - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть ограниченная задача оптимизации, где целевая функция является выпуклой при некоторых ограничениях неравенства по входному вектору. Единственная проблема заключается в том, что SLSQP утверждает, что ограничения несовместимы, что не соответствует действительности. Я проверил оба ограничения неравенства, используя начальный вектор, и они оба удовлетворены.

Я понимаю, что мою целевую функцию может быть трудно оптимизировать, но я думал, что включение якобиан во все поможет в решении этой проблемы. Кажется, должен быть какой-то параметр размера шага, который я мог бы настроить в решателе, чтобы исправить это, но изменение допусков для SLSQP, похоже, не решило проблему.

Ниже приведена упрощенная версия кода для одного экземпляра проблемы (в общем случае многие из этих переменных могут измениться, включая размерность вектора, над которым я оптимизируюсь), а также вывод, который он возвращает

import numpy as np
from scipy.optimize import minimize

###############################
# Problem Setup
###############################
omega = 2*np.pi/(1E-6)
r = 3.26

T = 1E-6/r
omega_s = 2*np.pi/T

yf = 120.E-6 
analytic_inf = 0.7611241494308488
analytic_inf_v = 43.30005226677565

n_vec = np.arange(1,4)
normalizing_vec = 1-n_vec**2*r**2

fqc_coeff = 7.422483151210897
fqc_mat = n_vec*omega_s/(1-(n_vec*r)**2)
fxd_mat = omega_s*n_vec

epsilon_coeff = 0.019552534524785916 
delta_coeff = 0.2015101389747311
alpha = 160.96016835831352

###############################
# Cost Function, Jacobians & Constraints
###############################
gaussian = lambda a: np.exp(-(fqc_coeff*(fqc_mat.dot(a)+omega_s/(2*np.pi))**2))
costa = lambda a: alpha*(1- gaussian(a))
costd = lambda a: delta_coeff*1/2*np.sum(a**2)
coste = lambda a: epsilon_coeff*1/2*np.sum((n_vec*2*np.pi*a)**2)

cost_f = lambda a: costa(a) + costd(a) + coste(a)

# Constraints
eqa = lambda a: (fqc_mat.dot(a) + omega_s/(2*np.pi))
ineqa = lambda a: eqa(a)*fqc_coeff + 1/np.sqrt(2)
jaca = lambda a: fqc_coeff*fqc_mat
ineqb = lambda a: -eqa(a)*fqc_coeff+ 1/np.sqrt(2)
jacb = lambda a: -fqc_coeff*fqc_mat
cons = [{'type':'ineq','fun':ineqa,'jac':jaca},
    {'type':'ineq','fun':ineqb,'jac':jacb}]

# Jacobian, if solver uses it
jacobian = lambda a: alpha*2*fqc_coeff**2*gaussian(a)*fqc_mat.dot(a)*fqc_mat + (
    delta_coeff*a) + (
    epsilon_coeff*(2*np.pi*n_vec)**2*a)

x0 = np.array([1.17120635, 0.54328102, 0.35740402])
result = minimize(cost_f, x0, method='SLSQP', jac=jacobian, 
    constraints=cons, options={'disp':True,'maxiter':1001,'ftol':1E-5})
print(ineqa(result.x))
print(ineqb(result.x))

А на выходе

Inequality constraints incompatible    (Exit mode 4)
            Current function value: 1.6377594465810514
            Iterations: 1
            Function evaluations: 1
            Gradient evaluations: 1
0.7431425286510408
0.6710710337220541
...