Python 3.x Pyomo ModelFactory(多个子模型的模型)的OOP设计
我已经用pyomo编写了模型,可以在输入不同类型的参数时正确求解。现在,我想在一个优化问题中同时解决其中几个模型。我想用面向对象的方法来实现这一点,而不需要重新编写大量代码。这可能吗 我已经尝试了许多块add_component()和块del_component()方法来复制属性,但还没有成功 导入并设置我的解算器后Python 3.x Pyomo ModelFactory(多个子模型的模型)的OOP设计,python-3.x,oop,pyomo,Python 3.x,Oop,Pyomo,我已经用pyomo编写了模型,可以在输入不同类型的参数时正确求解。现在,我想在一个优化问题中同时解决其中几个模型。我想用面向对象的方法来实现这一点,而不需要重新编写大量代码。这可能吗 我已经尝试了许多块add_component()和块del_component()方法来复制属性,但还没有成功 导入并设置我的解算器后 import pyomo.environ as pyo solver = pyo.SolverFactory('ipopt') 我在下面创建了一个模型类 class Model(
import pyomo.environ as pyo
solver = pyo.SolverFactory('ipopt')
我在下面创建了一个模型类
class Model(pyo.ConcreteModel):
"""
Model that solves the trivial equation $xy=z$,
where $x$ is a variable and $y$ and $z$ are parameters.
"""
def __init__(self, **kwargs):
"""
:param kwargs: keyword arguments that become attributes of model
"""
pyo.ConcreteModel.__init__(self)
self.x = pyo.Var()
self.y = pyo.Param(initialize=kwargs['y'])
self.z = pyo.Param(initialize=kwargs['z'])
self.constr = pyo.Constraint(expr=self.x*self.y==self.z)
self.obj = pyo.Objective(expr=1.)
这里的模型类设置了一个非常简单的问题来解决
现在,我想使用下面的ModelFactory类同时解决其中几个模型
class ModelFactory(pyo.ConcreteModel):
"""
class that contains many Model classes and combines them into
one single pyomo model that can be solved
"""
def __init__(self, y_params, z_params):
"""
:param y_params: values for parameters of y values for Model class
:type y_params: list
:param z_params: values for parameters of z values for Model class
:type z_params: list
"""
pyo.ConcreteModel.__init__(self)
for i in range(len(y_params)):
model_instance = Model(y=y_params[i], z=z_params[i])
objects = list(
model_instance.component_objects()
)
for obj in objects:
if str(obj) in self.__dict__:
# common attributes in pyo.ConcreteModel
continue
# copy and re-name all objects except the objective function
if not isinstance(obj, pyo.Objective):
setattr(self, str(obj) + '_%i'%i , obj)
self.obj = pyo.Objective(expr=1.)
我用以下代码测试代码
inst = ModelFactory([0, 4, 3, 2], [100, 22, 4, 2]) # initialize with arbitrary data
solver.solve(inst, tee=True)
我一直在使用setattr
命令时出错。
其中一个错误是
This behavior is not supported by Pyomo; components must have a
single owning block (or model), and a component may not appear
multiple times in a block. If you want to re-name or move this
component, use the block del_component() and add_component() methods.
有可能做到这一点吗?或者del_组件和add_组件非常复杂吗?我不确定我是否理解这个用例,但我认为您尝试通过索引块来做的可能是最简单的,每个块都用不同的数据初始化。你可以利用名称空间使数据多样化。我同意@GiorgioBalestrieri的观点,索引块是实现这一点的最佳方法。您可以重用单个构造规则来构建每个索引。我还建议使用包容设计模式,并使用包含Pyomo模型的类,而不是直接继承
ConcreteModel
。如果您对Pyomo的核心不太熟悉,那么继承Pyomo组件是非常困难的。我不确定我是否理解这个用例,但我认为您尝试通过索引块来做的可能是最简单的,每个块都用不同的数据初始化。你可以利用名称空间使数据多样化。我同意@GiorgioBalestrieri的观点,索引块是实现这一点的最佳方法。您可以重用单个构造规则来构建每个索引。我还建议使用包容设计模式,并使用包含Pyomo模型的类,而不是直接继承ConcreteModel
。如果您对Pyomo的核心不太熟悉,那么继承Pyomo组件是非常困难的。