我无法在此方面为您提供帮助,我有几个问题:
- 您知道是否在某处记录了对@ 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