Scipy最小化函数在初始猜测时停止

s2j5cfk0  于 8个月前  发布在  其他
关注(0)|答案(1)|浏览(51)

我试图建立一个脚本大小的坦克。在某些时候,我必须根据三个参数(A_frames,A_stringers和t_skin)最小化坦克的重量,我使用scipy的最小化函数和SLSQP方法来完成。
我从一个非常简单的案例开始,一开始没有任何限制。我必须最小化N_frames/N_stringers的不同组合的权重,但对于组合的3/4,scipy在初始猜测时停止优化,认为它是最小值,而实际上它显然不是(权重函数是线性的,非常简单!)
我完全不明白这一点,特别是因为它没有出现在其他方法中,如'L-BFGS-B',但我不能使用其他方法,因为它们没有考虑界限和/或约束。
如果有人对此有解释,那将对我有很大帮助
下面是出现问题的代码部分:

import numpy as np
import pandas as pd

from scipy.optimize import minimize

L_tank = 11
rho_s = 2850
rho_f= 2850
rho_skin = 2850
r_tank = 1.9

def Weight(X):
    A_frames = X[0]
    A_stringers = X[1]
    t_skin = X[2]
    return L_tank*A_stringers*rho_s*N_stringers + N_frames *A_frames*rho_f*2*np.pi*r_tank + 2*np.pi*r_tank*L_tank*t_skin*rho_skin

def grad_weight(X):
    A_frames = X[0]
    A_stringers = X[1]
    t_skin = X[2]
    grad = np.array([rho_f*2*np.pi*r_tank,  L_tank*rho_s*N_stringers ,  2*np.pi*r_tank*L_tank*rho_skin])
    return grad

for N_frames in range (4,40):
    for N_stringers in range (8,130,2):

        bnd = ((0.0, None), (0.0, None),(tshear, None))
        X0 = [0.001,0.000001,0.005]
        sol = minimize(Weight, x0 = X0,   bounds=bnd, method='SLSQP', jac = grad_weight)
           if sol.success:
                A_frames = sol.x[0]
                A_stringers = sol.x[1]
                t_skin = sol.x[2]
                weight = Weight(sol.x)
31moq8wy

31moq8wy1#

以下是人为的,但有助于说明问题。
你的优化目标是线性的,所以不要使用通用的minimize;使用LP,预先计算系数矩阵:

import numpy as np
from scipy.optimize import milp, Bounds

L_tank = 11
rho_s = rho_f = rho_skin = 2850
r_tank = 1.9
n_frames = np.arange(4, 40)
n_stringers = np.arange(8, 130, 2)
t_shear = 1  # entirely bogus

# All stringer terms, then all frame terms, then all skin terms
coeffs = np.stack(
    np.meshgrid(
        L_tank * rho_s * n_stringers,
         n_frames * rho_f * 2*np.pi * r_tank,
        (2*np.pi * r_tank * L_tank * rho_skin,),
    )
).reshape((3, -1)).ravel()

n_cases = coeffs.size // 3

res = milp(
    c=coeffs,
    integrality=0,
    bounds=Bounds(
        lb=np.concatenate((
            np.zeros(n_cases),
            np.zeros(n_cases),
            np.full(n_cases, fill_value=t_shear),
        ))
    ),
)
assert res.success, res.message
A_stringers, A_frames, t_skin = res.x.reshape((3, -1))

由于没有其他约束,目标系数都是正的,这是一个丢弃的LP结构,A_framesA_stringers将始终为0; t_skin将是您设置的t_shear

相关问题