【问题标题】:scipy.optimize.minimize does not converge in multivariable optimizationscipy.optimize.minimize 在多变量优化中不收敛
【发布时间】:2021-12-06 16:11:45
【问题描述】:

我想找到 board_trimlm 的值,这将为我提供 最低(最接近 0)值Board_Moments

为此,我使用 scipy.optimize.minimize,但它不会收敛。实在想不通。

参数

位移 = 70

b = 6.5

死角 = 20

LCG = 10

Vs_ms = 23.15 #ms

rho = 1025

mu = 1.19e-6

def Board_Moments(params):

    board_trim, lm = params

    displacement_N = displacement * 9.81 #kN  

    lp = Lp(Vs_ms, b, lm)
    N = displacement_N * cos(d2r(board_trim))             #Drag Forces Perpendicular to the keel

    #Taking moments about transom at height of CG

    deltaM = (displacement_N * LCG) - (N * lp) #equilibrium condition
    return deltaM

lp:

def Lp(Vs_ms, b, lm):

    cv = Cv(Vs_ms, b)
    Lambda = Lambda_(lm, b)
    Cp = 0.75 - (1 / (5.21 * (cv / Lambda)**2 + 2.39))
    lp = Cp * lm
    return lp

def Cv(Vs_ms, b):

    cv = Vs_ms / (9.81 * b)**0.5 
    return cv

def Lambda_(lm, b):

    lambda_ = lm / b
    return lambda_

优化完成:

board_trim = 2 #initial estimate

lm = 17.754 #initial estimate

x0 = [board_trim, lm]

Deltam = minimize(Board_Moments, x0, method = 'Nelder-Mead')
print(Deltam)

我得到的错误:

   final_simplex: (array([[ 1.36119237e+01,  3.45635965e+23],
   [-1.36046725e+01,  3.08439110e+23],
   [ 2.07268577e+01,  2.59841956e+23]]), array([-7.64916992e+25, 
   -6.82618616e+25, -5.53373709e+25]))

       fun: -7.649169916342451e+25

   message: 'Maximum number of function evaluations has been exceeded.'

      nfev: 401

       nit: 220

    status: 1

   success: False

         x: array([1.36119237e+01, 3.45635965e+23])

任何帮助将不胜感激,谢谢

【问题讨论】:

  • Vs_msb 是参数(待优化)还是常量?
  • 包括(失败的)最小化的结果。即,OptimizeResult,及其所有属性的值。
  • Vs_ms 和 b 是常量
  • 制作简单且可重复的示例,我们可能会提供更好的帮助
  • 请将错误添加到您的问题中(并格式化);这对问题很重要,在评论中不可读。

标签: python optimization scipy minimize convergence


【解决方案1】:

你提到

这将为我提供 Board_Moments 的最低(最接近 0)值。

但最小化将搜索绝对最小值。如果你打印deltaM 的中间值(你应该这样做来调试你的问题),你会发现它们变得越来越小,低于零(所以-10、-100、-500 等等。那种进展)。

要尽可能接近零,解决方案很简单:从Board_Moments 返回deltaM绝对值:

def Board_Moments(params):
    # code as before ...
    deltaM = (displacement_N * LCG) - (N * lp) #equilibrium condition
    
    # This print function would have shown the problem immediately
    #print(deltaM)

    # Use absolute (the built-in `abs` or `np.abs`; 
    # doesn't really matter for a single value)
    # to get close to zero
    return np.abs(deltaM)

对于这种特殊情况和修复,我得到的结果是:

final_simplex: (array([[ 2.32386388, 15.3390523 ],
       [ 2.32394414, 15.33905343],
       [ 2.32390145, 15.33905283]]), array([5.33445927e-08, 7.27723091e-08, 1.09428584e-07]))
           fun: 5.334459274308756e-08
       message: 'Optimization terminated successfully.'
          nfev: 107
           nit: 59
        status: 0
       success: True
             x: array([ 2.32386388, 15.3390523 ])

(如果你注释掉 print 函数,你会看到它很容易收敛到零。)

【讨论】:

    猜你喜欢
    • 2020-10-08
    • 2015-05-09
    • 2018-05-10
    • 2019-11-09
    • 1970-01-01
    • 1970-01-01
    • 2018-08-05
    • 1970-01-01
    • 2012-05-21
    相关资源
    最近更新 更多