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

问题描述 投票:0回答:1

我正在尝试构建一个脚本来确定水箱的大小。在某些时候,我必须根据三个参数(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)
python scipy minimize
1个回答
0
投票

以下内容是人为的,但可以说明问题。

您的优化目标是线性的,因此不要使用通用的

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_frames, A_stringers, t_skin = res.x.reshape((3, -1))

由于没有其他约束且目标系数均为正,因此这是一个一次性的 LP 构造,并且

A_frames
A_stringers
将始终为 0;
t_skin
将是您设置的
t_shear
的值。

© www.soinside.com 2019 - 2024. All rights reserved.