将pyomo对象组件代入sympy符号运算表达式的方法

Pyomo是一个基于python的开源软件包,它支持多种优化功能,用于制定和分析优化模型。

sympy是一个符号计算的Python库,支持符号计算、高精度计算、模式匹配、绘图、解方程、微积分、组合数学、离散 数学、几何学、概率与统计、物理学等方面的功能。

当我们在pyomo中构建优化问题时,经常需要对某一特定函数进行求导、积分等操作,一般需要手写推导,而Python中恰好有sympy符号运算库来帮我们做这个事情。

sympy中构建一个表达式之后,可以利用subs成员函数将表达式中的特定符号替换为我们想要的东西,代码示例如下

import sympy as sy

x = sy.symbols('x')
y = x**2 + x
y = y.subs(x, 2)
print(y)

结果为6,即2^2+2=6

subs函数也支持批量代入,代码示例如下

import sympy as sy

x, y = sy.symbols('x y')
z = x**2 + y**2
z = z.subs([(x, 2), (y, 3)])
print(z)

结果为13,即2^2+3^2=13

但是,pyomo对象组件无法直接代入sympy表达式从而获得pyomo表达式,因为sympy拒绝执行这种未定义的行为。

幸运的是,pyomo中提供了执行上述操作的工具。

首先,我们需要导入下面几个包

from pyomo.environ import *
import sympy as sy
from pyomo.core.expr.sympy_tools import sympy2pyomo_expression, PyomoSympyBimap

pyomo在pyomo.core.expr.sympy_tools中的函数sympy2pyomo_expression就是将sympy表达式转换为pyomo表达式,由于该转换需要用户提供sympy符号与pyomo符号的对应关系,因此需要用户额外构造一个PyomoSympyBimap对象。

现在假设我们有一个sympy表达式

x, y = sy.symbols('x y')
sympy_expr = x**2 + y**2

以及两个pyomo对象

m = ConcreteModel()
m.a = Var()
m.b = Var()

我们现在希望将sympy表达式中的x替换为m.a,y替换为m.b,从而得到形如m.a**2 + m.b**2的pyomo的表达式。

首先,我们需要利用PyomoSympyBimap建立sympy符号与pyomo符号的对应关系

bimap = PyomoSympyBimap()
bimap.sympy2pyomo = {x: m.a, y: m.b}

有了bimap就可以直接完成转换

pyomo_expr = sympy2pyomo_expression(sympy_expr, bimap)

转换后的pyomo_expr就可以直接在pyomo里面用了。

完整代码:

from pyomo.environ import *
import sympy as sy
from pyomo.core.expr.sympy_tools import sympy2pyomo_expression, PyomoSympyBimap

if __name__ == '__main__':
    x, y = sy.symbols('x y')
    sympy_expr = x ** 2 + y ** 2

    m = ConcreteModel()
    m.a = Var()
    m.b = Var()

    bimap = PyomoSympyBimap()
    bimap.sympy2pyomo = {x: m.a, y: m.b}

    pyomo_expr = sympy2pyomo_expression(sympy_expr, bimap)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值