Я написал модели на pyomo, которые могут корректно решать задачи при вводе с различными типами параметров.Теперь я хочу решить несколько из этих моделей одновременно в рамках задачи оптимизации.Я хотел бы сделать это в подходе ООП без переписывания большого количества кода.Возможно ли это?
Я пробовал многие методы блоков add_component () и del_component () блока, чтобы скопировать атрибуты, но у меня это не получилось.
После импорта инастройка моего решателя
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_component и add_component?