给出以下简单模型:
model.WEEKS = Set(initialize = [1,2,3])
model.PRODS = Set(initialize = ['Q24','J24','F24'])
model.volume = Var(model.WEEKS,model.PRODS, within = NonNegativeIntegers)
我想根据第二个索引的初始字符为
model.volume
中的每个排列设置不同的边界。目前,我通过对指定子集应用以下约束来实现这一目标:
# create subsets
Q_PRODS = Set(within = model.WEEKS * model.PRODS, initialize = [x for x in model.volume if x[1][0]=='Q'])
M_PRODS = Set(within = model.WEEKS * model.PRODS, initialize = [x for x in model.volume if x[1][0]!='Q'])
#define functions
def c1(model, i,j):
return (25, model.volume[i,j], 60)
model.c1 = Constraint(Q_PRODS, rule = c1)
def c2(model, i,j):
return (40, model.volume[i,j], 75)
model.c2 = Constraint(M_PRODS, rule = c2)
正确输出以下内容:
2 Constraint Declarations
c1 : Size=3, Index=c1_index, Active=True
Key : Lower : Body : Upper : Active
(1, 'Q24') : 25.0 : volume[1,Q24] : 60.0 : True
(2, 'Q24') : 25.0 : volume[2,Q24] : 60.0 : True
(3, 'Q24') : 25.0 : volume[3,Q24] : 60.0 : True
c2 : Size=6, Index=c2_index, Active=True
Key : Lower : Body : Upper : Active
(1, 'F24') : 40.0 : volume[1,F24] : 75.0 : True
(1, 'J24') : 40.0 : volume[1,J24] : 75.0 : True
(2, 'F24') : 40.0 : volume[2,F24] : 75.0 : True
(2, 'J24') : 40.0 : volume[2,J24] : 75.0 : True
(3, 'F24') : 40.0 : volume[3,F24] : 75.0 : True
(3, 'J24') : 40.0 : volume[3,J24] : 75.0 : True
但是,这似乎有点笨拙,我想知道是否有更有效的方法可以达到相同的目的?例如,通过定义在创建
model.volume
? 期间传递的规则
如果需要,您可以使用可调用函数来提供限制。对于大多数
Pyomo
构造,它必须捕获索引变量并且还具有对模型的自引用。 dox 中还有其他示例。
import pyomo.environ as pyo
m = pyo.ConcreteModel()
m.I = pyo.Set(initialize=[1, 2, 3, 4])
def v_limits(m, i):
if i%2==0:
return (10, 20)
return (8, 9)
m.X = pyo.Var(m.I, bounds=v_limits)
m.pprint()