单变量Scipy优化函数

gzszwxb4  于 2023-10-20  发布在  其他
关注(0)|答案(2)|浏览(87)

我尝试使用SciPy的minimize函数来最大化函数f的结果。但是,每次运行该脚本时,都会收到以下错误消息。

Exception has occurred: TypeError
'float' object is not iterable
  File "C:\Users\DonzaJ\OneDrive - LiRo Group\Desktop\Personal Files\Python Code\Fence Angle Optimizer.py", line 24, in <module>
    theta_final = spo.minimize(f, theta, method = 'SLSQP', options ={'disp':True}, bounds = bdns)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: 'float' object is not iterable

这是我到目前为止设置的脚本。

import scipy.optimize as spo
import math as m
import numpy as np

# Define Constants
fenceLength = 7.5 #ft
pointLoad = 500 #lbs
ex2 = 2 #in
ey2 = 4 #in

# Define Initial Variables
theta = np.ndarray(45.0) #degrees

# Define bounds for theta
bdns = (0.0, 90.0)

def f(X, *args):
    ex1 = (fenceLength/2)*m.cos(m.radians(theta))
    ey1 = (fenceLength/2)*m.sin(m.radians(theta))
    Y = m.sqrt(((pointLoad*(ey1+ey2))**2 + (pointLoad*(ex1+ex2))**2)) * -1
    return Y

# Call minimizer 
theta_final = spo.minimize(f, theta, method = 'SLSQP', options ={'disp':True}, bounds = bdns)

有谁能告诉我如何解决这个问题,我做错了什么?

zed5wv10

zed5wv101#

你的代码有几个问题。

  1. np.ndarray(45.0)不会生成numpy数组,你需要做一些类似np.array([45.0])的事情。但是,考虑到你只有一个变量,你可以只设置theta0 = 45.0
    1.正如在另一个答案中提到的,边界应该是一个对的序列,这意味着你应该将其定义为bnds = [(0.0, 90.0)]
    1.你的f函数需要使用你传递给它的变量,否则优化器将在结果中看不到任何变化,并假设它已经处于最小值。换句话说,你应该有ex1 = (fenceLength/2)*m.cos(m.radians(X))
    1.您的theta_final不会采用最佳值,但将是OptimizerResult,您需要从中获取值。
    下面是删除numpy导入的更新代码,因为它是不必要的,进行了上面概述的必要更改,并更新了一些符号以使其更加标准。
from scipy.optimize import minimize
import math

# Define Constants
fenceLength = 7.5 #ft
pointLoad = 500 #lbs
ex2 = 2 #in
ey2 = 4 #in

# Define Initial Variables
theta0 = 45.0 #degrees

# Define bounds for theta
bdns = [(0.0, 90.0)]

def f(X, *args):
    ex1 = (fenceLength/2)*math.cos(math.radians(X))
    ey1 = (fenceLength/2)*math.sin(math.radians(X))
    Y = -math.sqrt(((pointLoad*(ey1+ey2))**2 + (pointLoad*(ex1+ex2))**2))
    return Y

# Call minimizer 
res = minimize(f, theta0, method = "SLSQP", options={"disp":True}, bounds=bdns)
theta = res.x[0]
print(f"{theta = } deg")

输出量:

Optimization terminated successfully    (Exit mode 0)
            Current function value: -4111.067977477818
            Iterations: 4
            Function evaluations: 8
            Gradient evaluations: 4
theta = 63.43457272808145 deg
mefy6pfw

mefy6pfw2#

错误来自bounds参数。正如文档所述:
bound:序列或边界,Nelder-Mead、L-BFGS-B、TNC、SLSQP、Powell、trust-constr和COBYLA方法的变量的可选边界。有两种方法可以指定边界:

  1. Bounds类的示例。
  2. x中每个元素的(min,max)对序列。None用于指定无界限。
    您试图使用第二个选项,但您只有一个元组而不是一个元组序列。一个简单的解决办法是:
# Define bounds for theta
bdns = [(0.0, 90.0)]

相关问题