Scipy raise error, TypeError: unsupported operand type(s) for +: 'float' and 'dict' however the variables are float

Scipy raise error, TypeError: unsupported operand type(s) for +: 'float' and 'dict' however the variables are float

我正在尝试使用 scipy 优化一个受约束的非线性模型。

import numpy as np; from scipy.optimize import minimize; import math

# initial guesses
n = 2
x0 = np.zeros(n)
T = 0.1
L = 0.1


def objective(T, L):
    try:
        return (350 / T) + (35 * ((312.5 * (T / 2)) + (11.69 * (math.sqrt(T + L))) + (6.6256 * math.sqrt(T + L))))
    except ValueError:
        return None


def constraint1(T, L):
    (6.67 * math.sqrt(T + L) / (1250 * (T + L))) - 0.02


# show initial objective
print('Initial Objective: ' + str(objective(T, L)))

# optimize
con1 = {'type': 'ineq', 'fun': constraint1}
cons = ([con1])
solution = minimize(objective, x0, args=cons)
x = solution.x

# show final objective
print('Final  Objective: ' + str(objective(T, L)))

# print solution
print('Solution'); print('x1 = ' + str(x[0])); print('x2 = ' + str(x[1]))

当我运行代码时,我得到了错误,

line 24, in objective return (350 / T) + (35 * ((312.5 * (T / 2)) + (11.69 * (math.sqrt(T + L))) + (6.6256 * math.sqrt(T + L)))) TypeError: unsupported operand type(s) for +: 'float' and 'dict'

在 objective(T,L) 上,T 描述为,

Parameter T of scipyProject.constraint1 T: {truediv, add} pythonProject

但在 constraint1(T, L)

Parameter T of scipyProject.constraint1 T: {add} pythonProject

你能帮我吗,为什么我会收到这个错误?

我运行你的代码调试一下。我注意到以下内容并进行了相应的更改:

  • 函数 constraint1(T, L) 没有 return 任何东西。
  • 因为 @ForceBru mentioned, using args=cons will pass the dictionary you made for the constraints as args to your objective function. The scipy documentation 定义 objective 函数将 NumPy 数组作为单个参数。
  • objective 函数计算 math.sqrt(T+L),并且没有提及 T+L > 0 的约束。当我修复之前的问题时,math.sqrt 函数出现域错误。我查看了这个 by @Peter 并决定使用 `safeSqrt' 函数做一些类似的事情。

这是经过一些更改后的代码。 (顺便说一句,我对这个等式不太了解,但看起来设置 L = -T 总是好的。所以你可以消除一些项并针对单个变量进行优化。)

import numpy as np
from scipy.optimize import minimize
import math

T = 0.1
L = 0.1
x0 = np.array([T, L])


def safeSqrt(s):
    # extend math.sqrt with a safe function
    # ref: 
    return math.sqrt(s) if s > 0 else 0

def objective(x):
    T, L = x[0], x[1]
    linearPart = (312.5 * T / 2)
    sqrtPart = (11.69 + 6.6256) * safeSqrt(T + L)
    return 10 / T + (linearPart + sqrtPart) # your original objective was 35 times this value 

def constraint(x):
    T, L = x[0], x[1]
    result = 6.67 / (1250 * .02) - safeSqrt(T+L) # equivalent to your original constraint
    return result

# show initial objective
print('Initial Objective: ' + str(objective(x0)))
print("contraint: ", constraint(x0))

# optimize
solution = minimize(objective, x0, constraints={"fun": constraint, "type": "ineq"})

x = solution.x

# show final objective
print('Final  Objective: ' + str(objective(x)))

# print solution
print('Solution')
print('x1 = ' + str(x[0]))
print('x2 = ' + str(x[1]))

代码输出为:

Initial Objective: 115.625
contraint:  -0.18041359549995795   
Final  Objective: 79.05694150421618
Solution
x1 = 0.25298231697349643
x2 = -1.5173265889148493

如果这是您想要的,请告诉我:)