如何在课程中使用Pyomo装饰器

下面是一个使用装饰器语法的简单Pyomo脚本-我想了解如何在类中使用此语法-在这种情况下,在LockTimeoutException will内部。

无类版本

Model

无法使用的类中的装饰器版本:

from pyomo.environ import *

import random

random.seed(1000)

model = AbstractModel()

model.N = Param(within=PositiveIntegers)
model.P = Param(within=RangeSet(1,model.N))
model.M = Param(within=PositiveIntegers)

model.Locations = RangeSet(1,model.N)
model.Customers = RangeSet(1,model.M)

model.d = Param(
    model.Locations,model.Customers,initialize=lambda n,m,model: random.uniform(1.0,2.0),within=Reals,)

model.x = Var(model.Locations,bounds=(0.0,1.0))
model.y = Var(model.Locations,within=Binary)


@model.Objective()
def obj(model):
    return sum(
        model.d[n,m] * model.x[n,m] for n in model.Locations for m in model.Customers
    )


@model.Constraint(model.Customers)
def single_x(model,m):
    return (sum(model.x[n,m] for n in model.Locations),1.0)


@model.Constraint(model.Locations,model.Customers)
def bound_y(model,n,m):
    return model.x[n,m] - model.y[n] <= 0.0


@model.Constraint()
def num_facilities(model):
    return sum(model.y[n] for n in model.Locations) == model.P
ngd267cui 回答:如何在课程中使用Pyomo装饰器

我无法在此方面为您提供帮助,我有几个问题:

  • 您知道是否在某处记录了对@ model.Objective()的使用(与Constraint等相同)吗?我不知道它的存在,而且很棒
  • 为什么要让您的“功能规则”成为课程的方法?您不能将它们定义为__init__方法中的函数吗?

我想我首先缺少的是使用类的好处。 如果您只是想以某种方式包装模型构造,那么更好的方法是使用函数:

def create_model():
    model = AbstractModel()

    ...

    @model.Constraint()
    def some_rule_function(model):
        ...

    ...

    return model

编辑:如果您真的想将所有内容包装到一个类中:

class Model:
    def __init__(self,model):
         self.model = model

    # alternative constructor:
    # def __init__(self):
    #     self.model = create_model()

    def construct(self,data):
        # get concrete model
        self.model = self.model.create_instance(data)

    def run(self,solver,**kwargs):
        with pe.SolverFactory(solver) as solver:
            solver.solve(self.model,**kwargs)

    def construct_and_run(self,data,**kwargs):
        self.construct(data)
        self.data(solver,**kwargs)

    # other behavior you want to add to the class

用法示例:

model = Model(create_model())
,

尝试回答您的直接问题,这似乎对我有用。我的解释是,由于您的模型称为self.model,因此装饰器也应与此匹配。

请注意,我使用s作为约束方法定义中的第一个参数,只是为了查看它是否有效,但也可以是model或您想调用的任何东西。

class Model:
    def __init__(self):
        self.model = pyo.AbstractModel()

        self.model.N = pyo.Param(initialize=5,within=pyo.PositiveIntegers)
        self.model.P = pyo.Param(initialize=3,within=pyo.RangeSet(1,self.model.N))
        self.model.M = pyo.Param(initialize=3,within=pyo.PositiveIntegers)

        self.model.Locations = pyo.RangeSet(1,self.model.N)
        self.model.Customers = pyo.RangeSet(1,self.model.M)

        self.model.d = pyo.Param(
            self.model.Locations,self.model.Customers,initialize=lambda n,m,model: random.uniform(1.0,2.0),within=pyo.Reals,)

        self.model.x = pyo.Var(
            self.model.Locations,bounds=(0.0,1.0)
        )
        self.model.y = pyo.Var(self.model.Locations,within=pyo.Binary)

        @self.model.Objective()
        def obj(s):
            return sum(
                s.d[n,m] * s.x[n,m]
                for n in s.Locations
                for m in s.Customers
            )

        @self.model.Constraint(self.model.Customers)
        def single_x(s,m):
            return (sum(s.x[n,m] for n in s.Locations),1.0)

        @self.model.Constraint(self.model.Locations,self.model.Customers)
        def bound_y(s,n,m):
            return s.x[n,m] - s.y[n] <= 0.0

        @self.model.Constraint()
        def num_facilities(s):
            return sum(s.y[n] for n in s.Locations) == s.P

然后,您将能够使用model = Model()实例化模型,尽管很烦人(至少对我来说是这样),但是所有Pyomo模型组件都将位于属性model.model中(例如{{1} }。

我为使命名更简洁之前所做的工作是从AbstractModel继承(尽管其他答案表明这可能不是一个好习惯):

model.model.P

在这种情况下,您仍将实例化为from pyomo.core.base.PyomoModel import AbstractModel class Model(AbstractModel): def __init__(self): AbstractModel.__init__(self) self.N = pyo.Param(initialize=5,within=pyo.PositiveIntegers) self.P = pyo.Param(initialize=3,self.N)) self.M = pyo.Param(initialize=3,within=pyo.PositiveIntegers) self.Locations = pyo.RangeSet(1,self.N) self.Customers = pyo.RangeSet(1,self.M) self.d = pyo.Param( self.Locations,self.Customers,) self.x = pyo.Var( self.Locations,1.0) ) self.y = pyo.Var(self.Locations,within=pyo.Binary) @self.Objective() def obj(s): return sum( s.d[n,m] for n in s.Locations for m in s.Customers ) @self.Constraint(self.Customers) def single_x(s,1.0) @self.Constraint(self.Locations,self.Customers) def bound_y(s,m] - s.y[n] <= 0.0 @self.Constraint() def num_facilities(s): return sum(s.y[n] for n in s.Locations) == s.P ,但可以以model = Model()的方式访问Pyomo模型组件。

本文链接:https://www.f2er.com/3021595.html

大家都在问