Pyomo 中索引集的累积约束表达式

问题描述 投票:0回答:1

使用以下简化模型:

model = ConcreteModel()

model.WEEKS = Set(initialize = [1,2,3])
model.PRODS = Set(initialize = ['Q24','J24','F24'])
model.MONTHS = Set(initialize = ['J24','F24'])

model.volume = Var(model.WEEKS,model.PRODS, within = NonNegativeIntegers)
model.auction = Var(model.WEEKS,model.PRODS, within = Binary)

model.HedgeMin = Param(model.WEEKS,model.MONTHS, within = NonNegativeIntegers, initialize = {(1,'J24'):45,(1,'F24'):45,
                                                                                (2,'J24'):90,(2,'F24'):90,
                                                                                (3,'J24'):135,(3,'F24'):135})

model.HedgeMax = Param(model.WEEKS,model.MONTHS, within = NonNegativeIntegers, initialize = {(1,'J24'):60,(1,'F24'):60,
                                                                                (2,'J24'):120,(2,'F24'):120,
                                                                                (3,'J24'):180,(3,'F24'):180})

我正在尝试构建一个约束,将累积边界应用于

auction
中每周和
volume
中每月的
model.WEEKS
*
model.MONTHS
的乘积。使用@AirSquid对此post的回复的有用指导,我构建了以下内容:

def hedge_rule(model, i,j):
        subset = {x for x in model.WEEKS if x <= i}
        return (model.HedgeMin[i,j],
               sum(model.auction[i,j] * model.volume[i,j] for i in subset for j in model.MONTHS)
                model.HedgeMax[i,j])
model.hedge_const = Constraint(model.WEEKS,model.MONTHS, rule = hedge_rule)

这会产生以下约束:

hedge_const : Size=6, Index=hedge_const_index, Active=True
    Key        : Lower : Body                                                                                                                                                                                    : Upper : Active
    (1, 'F24') :  45.0 :auction[1,J24]*volume[1,J24] + auction[1,F24]*volume[1,F24] :  60.0 :True
    (1, 'J24') :  45.0 :auction[1,J24]*volume[1,J24] + auction[1,F24]*volume[1,F24] :  60.0 :True
    (2, 'F24') :  90.0 :auction[1,J24]*volume[1,J24] + auction[1,F24]*volume[1,F24] + auction[2,J24]*volume[2,J24] + auction[2,F24]*volume[2,F24] : 120.0 :   True
    (2, 'J24') :  90.0 :auction[1,J24]*volume[1,J24] + auction[1,F24]*volume[1,F24] + auction[2,J24]*volume[2,J24] + auction[2,F24]*volume[2,F24] : 120.0 :   True
    (3, 'F24') : 135.0 : auction[1,J24]*volume[1,J24] + auction[1,F24]*volume[1,F24] + auction[2,J24]*volume[2,J24] + auction[2,F24]*volume[2,F24] + auction[3,J24]*volume[3,J24] + auction[3,F24]*volume[3,F24] : 180.0 :   True
    (3, 'J24') : 135.0 : auction[1,J24]*volume[1,J24] + auction[1,F24]*volume[1,F24] + auction[2,J24]*volume[2,J24] + auction[2,F24]*volume[2,F24] + auction[3,J24]*volume[3,J24] + auction[3,F24]*volume[3,F24] : 180.0 :   True

我相信,因为我对集合

auction[i,j]*volume[i,j]
求和
model.MONTHS
,所以
J24
F24
都包含在每个集合声明中。因此,例如:
(1, 'F24')
=
45.0 :auction[1,J24]*volume[1,J24] + auction[1,F24]*volume[1,F24] :  60.0
.

但是,我希望每个键仅包含相关月份。即

(1, 'F24')
=
45.0 :auction[1,F24]*volume[1,F24] :  60.0

(1, 'J24')
=
45.0 :auction[1,J24]*volume[1,J24] :  60.0

(2, 'F24')
=
90.0 :auction[1,F24]*volume[1,F24] + auction[2,F24]*volume[2,F24] : 120.0

(2, 'J24')
=
90.0 :auction[1,J24]*volume[1,J24] +   auction[2,J24]*volume[2,J24] : 120.0
等等

我的问题是,这是否可以通过

model.hedge_rule
的单一定义来实现?我想该解决方案需要为
MONTHS
中的每个元素创建单独的集合,但我不太确定如何实现它。

一如既往,非常感谢帮助和指导!

python pyomo
1个回答
0
投票

尚不完全清楚

MONTHS
是什么,但您绝对应该避免重复那里的另一组值,除非它是某种子集。

我认为您对特定产品与某些周有某种关联,因此以下是我将采取的方法。您有效地制作了一组稀疏的

WEEKS * PRODS
并使用它,这很好。

您可以搜索我的其他答案“索引集”,我已经发布了其他类似的建议。

OBTW:您似乎(无意中?)构建了一个非线性(因为您正在乘以变量)整数程序,这将很难解决。如果可能的话,您应该考虑重新制定 MILP。如果这是可接受的简化,则可以考虑将

volume
设为连续变量而不是整数。也许考虑制定一个大 M 约束而不是乘以变量。

代码:

from pyomo.environ import ConcreteModel, Set, Var, Constraint

weekly_products = {
    1: ['Q24', 'J24'],
    2: ['Q24', 'F24'],
    3: ['F24']
}

model = ConcreteModel()

model.WEEKS = Set(initialize = [1,2,3])
model.PRODS = Set(initialize = ['Q24','J24','F24'])
# model.MONTHS = Set(initialize = ['J24','F24'])  <-- don't do this.  :)

# this is an "indexed set" which is a set of sets, indexed in this case by WEEKS
model.WEEK_PROD = Set(model.WEEKS, initialize=weekly_products)
model.WEEK_PROD_flat = Set(initialize=[(w, p) for w in model.WEEKS for p in model.WEEK_PROD[w]])

# initializing X with this reduced flat set will reduce errors and build a more compact
# model instead of |weeks| * |products| if there are only sparse legal combinations to consider:
model.X = Var(model.WEEK_PROD_flat)

def limit_rule(m, week):
    return (5, sum(m.X[week, product] for product in m.WEEK_PROD[week]), 10)

model.C1 = Constraint(model.WEEKS, rule=limit_rule)

model.pprint()

输出:

 4 Set Declarations
    PRODS : Size=1, Index=None, Ordered=Insertion
        Key  : Dimen : Domain : Size : Members
        None :     1 :    Any :    3 : {'Q24', 'J24', 'F24'}
    WEEKS : Size=1, Index=None, Ordered=Insertion
        Key  : Dimen : Domain : Size : Members
        None :     1 :    Any :    3 : {1, 2, 3}
    WEEK_PROD : Size=3, Index=WEEKS, Ordered=Insertion
        Key : Dimen : Domain : Size : Members
          1 :     1 :    Any :    2 : {'Q24', 'J24'}
          2 :     1 :    Any :    2 : {'Q24', 'F24'}
          3 :     1 :    Any :    1 : {'F24',}
    WEEK_PROD_flat : Size=1, Index=None, Ordered=Insertion
        Key  : Dimen : Domain : Size : Members
        None :     2 :    Any :    5 : {(1, 'Q24'), (1, 'J24'), (2, 'Q24'), (2, 'F24'), (3, 'F24')}

1 Var Declarations
    X : Size=5, Index=WEEK_PROD_flat
        Key        : Lower : Value : Upper : Fixed : Stale : Domain
        (1, 'J24') :  None :  None :  None : False :  True :  Reals
        (1, 'Q24') :  None :  None :  None : False :  True :  Reals
        (2, 'F24') :  None :  None :  None : False :  True :  Reals
        (2, 'Q24') :  None :  None :  None : False :  True :  Reals
        (3, 'F24') :  None :  None :  None : False :  True :  Reals

1 Constraint Declarations
    C1 : Size=3, Index=WEEKS, Active=True
        Key : Lower : Body                : Upper : Active
          1 :   5.0 : X[1,Q24] + X[1,J24] :  10.0 :   True
          2 :   5.0 : X[2,Q24] + X[2,F24] :  10.0 :   True
          3 :   5.0 :            X[3,F24] :  10.0 :   True

6 Declarations: WEEKS PRODS WEEK_PROD WEEK_PROD_flat X C1
© www.soinside.com 2019 - 2024. All rights reserved.