目前,我有以下代码定义函数func
from scipy.optimize import minimize
import sympy as sp
x2=sp.Symbol('x2')
u2=sp.Symbol('u2')
fm=25*u2-20.0*(sp.sin(x2)) + 38.7296387*(sp.cos(x2)) - 38.7296387
def func(x2,u2):
return -fm
def constraint1(u2,x2):
return -u2+40*sp.sin(x2)+0.2
def constraint2(u2,x2):
return -u2-40*sp.sin(x2)+0.2
b=[-1,1]
bnds=[b,b]
con1 = {'type': 'ineq', 'fun': constraint1}
con2 = {'type': 'ineq', 'fun': constraint2}
cons = ([con1,con2])
x0=[0,0]
solution = minimize(func,x0,method='SLSQP',bounds=bnds,constraints=cons)
关于x2和u2,我正在最小化f。SciPy的优化工具箱不允许最小化参数中带有Sympy变量的函数。有什么办法我能做到这一点吗?
SymPy是符号数学库,而SciPy是数字数学库。SciPy不理解与SymPy的符号有关的任何内容,它只能处理浮点等数值。
为了避免混淆,您必须尝试使每个变量都有自己的名称。这意味着要将x
的数值与其符号值清楚地分开。例如,在func
中,可能由于这种混淆,您对输入值x2
和u2
不做任何操作。fm
是SciPy不理解的符号表达。要从fm
获得浮点值,需要在某个点使用subs()
对其进行求值。
第二个错误是SciPy使用了接受单个元组输入的函数,而不是具有多个浮点输入的函数。您需要在函数中自己分离输入。
第三个错误是在func
、constraint1
和constraint2
之间交换x2
和u2
。这将导致条件的输入被交换,这将创建与您期望的完全不同的约束。
这是你的代码与这3个修复:
from scipy.optimize import minimize
import sympy as sp
x2_symbol = sp.Symbol('x2')
u2_symbol = sp.Symbol('u2')
fm = 25 * u2_symbol - 20.0 * (sp.sin(x2_symbol)) + 38.7296387 * (sp.cos(x2_symbol)) - 38.7296387
def func(x):
x2_float, u2_float = x
return -fm.subs([(x2_symbol, x2_float), (u2_symbol, u2_float)])
def constraint1(x):
x2_float, u2_float = x
return -u2_float + 40 * sp.sin(x2_float) + 0.2
def constraint2(x):
x2_float, u2_float = x
return -u2_float - 40 * sp.sin(x2_float) + 0.2
b = [-1, 1]
bounds = [b, b]
con1 = {'type': 'ineq', 'fun': constraint1}
con2 = {'type': 'ineq', 'fun': constraint2}
constraints = (con1, con2)
x0 = [0, 0]
solution = minimize(func, x0, method='SLSQP', bounds=bounds, constraints=constraints)
print(solution)
我认为fm
是从以前的另一个问题的解决方案中实现的,因此必须包含符号。如果没有,这个问题可以完全用数字来解决,只需对上面的代码进行很少的更改。
您也可以使用卡鲁什-库恩-塔克条件纯粹象征性地解决这个问题。如果我觉得可以的话,我可以发布一个解决方案。