【问题标题】:SciPy Optimizer gives result that do not satisfy constraintsSciPy Optimizer 给出不满足约束的结果
【发布时间】:2020-08-05 01:54:31
【问题描述】:

我正在使用 scipy.optimize.minimize 解决一个问题,但是包给出的结果违反了约束。

这种情况非常简单,只给出了一个目标函数和一个约束。代码如下:

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

这显然违反了一个(也是唯一一个)约束。

任何想法我做错了什么?谢谢

【问题讨论】:

    标签: python-3.x scipy-optimize scipy-optimize-minimize


    【解决方案1】:

    优化不成功。您可以看到解决方案报告失败......至少它知道它无法满足约束。

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

    优化失败的原因是约束中的最大函数。 Sequential quadratic programming 基于线性化约束。在局部,(不满足的)约束线性化为一个常数值,因此迭代解决方案看不到任何满足该约束的进展 - 每次迭代都会降低目标而不会朝着解决方案取得进展。

    我将约束更改为在区域中不平坦,以允许算法逐步改进它并且优化成功。

    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
    

    这可能是您实际尝试强制执行的约束,但也许您可以平滑地逼近您的约束并获得成功。

    【讨论】:

    • 很好的近似方法。赞赏!
    猜你喜欢
    • 2015-12-11
    • 1970-01-01
    • 2022-11-10
    • 2016-04-16
    • 2016-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多