消除 pyomo 模型中的等式约束
Eliminate equality constraints in a pyomo model
我想通过替换消除 pyomo 模型中积分变量的线性等式约束。例如,我希望转换模型
代入
( * )
到
有没有办法在 pyomo 模型中执行这样的替换?我将能够通过计算 y = const_vec + susbtitution_matrix * eta
形式的相应线性丢番图方程组的解 space 来获得 ( * ),在我们的示例中,我们有
const_vec = np.array([1,0,0])
substitution_matrix = np.array([[-1,0],
[1,0],
[0,1]])
你所描述的通常被称为"variable aggregation."正如你所指出的,有四个基本步骤:
- 确定要删除的线性等式
- 计算替换图
- 停用您要删除的等式约束
- 替换所有剩余约束的变量
听起来你控制了 1 和 2。对于 3,假设您确定了要停用的约束 m.c
,您只需调用 m.c.deactivate()
.
对于 4,您将希望为剩余的约束“body
”表达式生成新表达式(变量仅出现在正文中,而不出现在 lower/upper 边界中)。对于当前的 Pyomo 版本(通过 5.4.x),您可以利用 clone_expression()
执行变量替换。您需要生成一个 "substitution map": 一个字典,它将您想要的变量的 id()
映射到您想要使用的新表达式。例如:
from pyomo.core.base.expr import clone_expression
m = ConcreteModel()
m.y = Var([1,2,3])
m.eta = Var([1,2])
# ...
m.c = Constraint(expr=m.y[1]**2 + m.y[3]**2 <= 4)
# ...
substitution_map = {
id(m.y[1]): 1 - m.eta[1],
id(m.y[2]): m.eta[1],
id(m.y[3]): m.eta[2],
}
m.c = (m.c.lower, clone_expression(m.c.body, substitute=substitution_map), m.c.upper)
最后,免责声明:
- 使用此语法设置约束应该适用于最近的 Pyomo 版本(我通过 5.1 测试过)
- 这种方法在技术上违反了当前 Pyomo 表达式系统中的假设之一(它可能生成 "entangled" 表达式:共享公共 sub-trees 的表达式)。虽然不是 "good",但应该不会造成麻烦,除非您进行额外的转换/表达式操作。
- Pyomo 5.5 将有一个新的表达系统,可能会有不同的机制来操纵/替换变量。
我想通过替换消除 pyomo 模型中积分变量的线性等式约束。例如,我希望转换模型
代入
到
有没有办法在 pyomo 模型中执行这样的替换?我将能够通过计算 y = const_vec + susbtitution_matrix * eta
形式的相应线性丢番图方程组的解 space 来获得 ( * ),在我们的示例中,我们有
const_vec = np.array([1,0,0])
substitution_matrix = np.array([[-1,0],
[1,0],
[0,1]])
你所描述的通常被称为"variable aggregation."正如你所指出的,有四个基本步骤:
- 确定要删除的线性等式
- 计算替换图
- 停用您要删除的等式约束
- 替换所有剩余约束的变量
听起来你控制了 1 和 2。对于 3,假设您确定了要停用的约束 m.c
,您只需调用 m.c.deactivate()
.
对于 4,您将希望为剩余的约束“body
”表达式生成新表达式(变量仅出现在正文中,而不出现在 lower/upper 边界中)。对于当前的 Pyomo 版本(通过 5.4.x),您可以利用 clone_expression()
执行变量替换。您需要生成一个 "substitution map": 一个字典,它将您想要的变量的 id()
映射到您想要使用的新表达式。例如:
from pyomo.core.base.expr import clone_expression
m = ConcreteModel()
m.y = Var([1,2,3])
m.eta = Var([1,2])
# ...
m.c = Constraint(expr=m.y[1]**2 + m.y[3]**2 <= 4)
# ...
substitution_map = {
id(m.y[1]): 1 - m.eta[1],
id(m.y[2]): m.eta[1],
id(m.y[3]): m.eta[2],
}
m.c = (m.c.lower, clone_expression(m.c.body, substitute=substitution_map), m.c.upper)
最后,免责声明:
- 使用此语法设置约束应该适用于最近的 Pyomo 版本(我通过 5.1 测试过)
- 这种方法在技术上违反了当前 Pyomo 表达式系统中的假设之一(它可能生成 "entangled" 表达式:共享公共 sub-trees 的表达式)。虽然不是 "good",但应该不会造成麻烦,除非您进行额外的转换/表达式操作。
- Pyomo 5.5 将有一个新的表达系统,可能会有不同的机制来操纵/替换变量。