SciPy中Sympy变量最小化函数



目前,我有以下代码定义函数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中,可能由于这种混淆,您对输入值x2u2不做任何操作。fm是SciPy不理解的符号表达。要从fm获得浮点值,需要在某个点使用subs()对其进行求值。

第二个错误是SciPy使用了接受单个元组输入的函数,而不是具有多个浮点输入的函数。您需要在函数中自己分离输入。

第三个错误是在funcconstraint1constraint2之间交换x2u2。这将导致条件的输入被交换,这将创建与您期望的完全不同的约束。

这是你的代码与这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是从以前的另一个问题的解决方案中实现的,因此必须包含符号。如果没有,这个问题可以完全用数字来解决,只需对上面的代码进行很少的更改。

您也可以使用卡鲁什-库恩-塔克条件纯粹象征性地解决这个问题。如果我觉得可以的话,我可以发布一个解决方案。

最新更新