Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x Pyomo ModelFactory(多个子模型的模型)的OOP设计_Python 3.x_Oop_Pyomo - Fatal编程技术网

Python 3.x Pyomo ModelFactory(多个子模型的模型)的OOP设计

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(

我已经用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_组件和add_组件非常复杂吗?

我不确定我是否理解这个用例,但我认为您尝试通过索引块来做的可能是最简单的,每个块都用不同的数据初始化。你可以利用名称空间使数据多样化。我同意@GiorgioBalestrieri的观点,索引块是实现这一点的最佳方法。您可以重用单个构造规则来构建每个索引。我还建议使用包容设计模式,并使用包含Pyomo模型的类,而不是直接继承
ConcreteModel
。如果您对Pyomo的核心不太熟悉,那么继承Pyomo组件是非常困难的。我不确定我是否理解这个用例,但我认为您尝试通过索引块来做的可能是最简单的,每个块都用不同的数据初始化。你可以利用名称空间使数据多样化。我同意@GiorgioBalestrieri的观点,索引块是实现这一点的最佳方法。您可以重用单个构造规则来构建每个索引。我还建议使用包容设计模式,并使用包含Pyomo模型的类,而不是直接继承
ConcreteModel
。如果您对Pyomo的核心不太熟悉,那么继承Pyomo组件是非常困难的。