SciPy Optimizer дает результат, не удовлетворяющий ограничениям - PullRequest
1 голос
/ 05 августа 2020
• 1000 Вот код:
   import math
   import numpy as np
   import scipy
   from scipy.optimize import minimize

   def objective(x):
       return np.sum(np.dot(x,x))
   n = 5
   X_bound=[(0,4) for i in range(n)]
   X_guess=[1 for i in range(n)]
   _tmp = []
  func_list = []

  def temp_func(X):
      total = 0
      for i in range(n):
          total = total + np.maximum(X[i] * 5 - 6, 0)
      return total/n - 1
  func_list.append(temp_func)
  for ii in range(len(func_list)):
  _tmp.append({'type': 'ineq', 'fun': func_list[ii]})
  X_constraint=_tmp

  sol=scipy.optimize.minimize(objective,X_guess,method='SLSQP',bounds=X_bound,
                        constraints=X_constraint)
  result = sol.x
  result

Результатом приведенного выше кода является

array([5.61582806e-12, 3.56925226e-12, 3.57912934e-12, 3.57912933e-12, 3.57872619e-12])

, что, очевидно, нарушает одно (и только) ограничение.

Любые идеи что я делаю не так? Спасибо

1 Ответ

1 голос
/ 05 августа 2020

Оптимизация не выполняется. Вы можете видеть, что решение сообщает об ошибке ... по крайней мере, оно знает, что не может удовлетворить ограничение.

>>> result
array([5.61582806e-12, 3.56925226e-12, 3.57912934e-12, 3.57912933e-12,
       3.57872619e-12])
>>> temp_func(result)
-1.0
>>> sol
     fun: 8.270470124157974e-23
     jac: array([1.49123928e-08, 1.49082997e-08, 1.49083195e-08, 1.49083195e-08,
       1.49083186e-08])
 message: 'Iteration limit exceeded'
    nfev: 1697
     nit: 101
    njev: 101
  status: 9
 success: False
       x: array([5.61582806e-12, 3.56925226e-12, 3.57912934e-12, 3.57912933e-12,
       3.57872619e-12])

Причиной сбоя оптимизации является максимальная функция в ограничении. Последовательные квадраты c программирование основано на линеаризации ограничений. Локально (неудовлетворенное) ограничение линеаризуется до постоянного значения, поэтому итеративное решение не видит никакого способа добиться прогресса, удовлетворяющего этому ограничению - каждая итерация снижает цель, не продвигаясь к решению.

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

def temp_func(X):
  total = 0
  for i in range(n):
      val = total+X[i]*5 - 6
      if val < 0:
        val = np.arctan(val)
      total = val
  return total/n - 1

Это, вероятно, ограничение, которое вы на самом деле пытаетесь реализовать, но, возможно, вы можете плавно аппроксимировать свое ограничение получить что-то успешное.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...