Pyomo 约束声明

问题描述

pyomo 的初学者,我有一个问题来编码我的约束

这是我的输入数据:

S = ['E','L'] #shits
N = [0,1,2,3,4,5,6,7,8,9] #employee ID
D = [1,3] #days
R = {(1,'D'): 1,(1,'N'): 1,(2,(3,'D'): 2,'N'):3} # cover requirement {(day,shift):number of employees required}

我做了这样的集合声明:

model.N = Set(initialize = N)
model.S = Set(initialize = S)
model.D = Set(initialize = D)

model.N_S_D = Set(within = model.N * model.S * model.D,initialize = [(n,s,d) for n in model.N for s in model.S for d in model.D])

决策变量声明:

model.x = Var(model.N_S_D,within=Binary,initialize=0)

约束声明,约束是

enter image description here

(在我的模型中 ˜r 是 R)

model.C1 = ConstraintList()
for N in model.N_S_D:
    const_expr = sum(model.x[(d,s) == R[(d,s)]])
    model.C1.add(expr = const_expr)

所有单元格都可以正常工作,但出现错误的约束之一除外:NameError: name 'd' is not defined。出现此错误,我想知道我的设置声明 model.N_S_D 是否正确。其次,我不知道如何声明集合覆盖要求(R),我是否应该这样做?谢谢

解决方法

您的代码中有几个问题。

  • 您的班次设置不匹配。 (见下面我的)
  • 当您看到“for each”符号时,您需要为集合或组合集合的每个元素创建一个约束……您求和的内容需要在求和表达式内,并且您需要遍历“foreaches”是一个很好的思考方式……我认为你被打败了。
  • 您没有正确制定 sum() 表达式。您需要在求和的事物中定义索引的来源。我建议您在 pyomo 之外尝试一些带有 sum() 的练习题,以便更好地处理它。
  • 将来,如果您将所有代码以工作(或至少会产生错误)格式粘贴到一个块中,以便有人可以直接复制并对其进行处理,则会更有帮助。

以下是解决您问题的两种不同方法。首先是使用带有 ConstraintList 的方法。替代方法使用函数-约束组合,我觉得这更容易,但任何一种都有效......只是不要包含两者,因为它们是多余的。 :)

from pyomo.environ import *

S = ['D','N'] #shifts
N = [0,1,2,3,4,5,6,7,8,9] #employee ID
D = [1,3] #days
R = {   (1,'D'): 1,(1,'N'): 1,(2,(3,'D'): 2,'N'): 3} # cover requirement {(day,shift):number of employees required}


model = ConcreteModel('shift schedule')
model.N = Set(initialize = N)
model.S = Set(initialize = S)
model.D = Set(initialize = D)

model.N_S_D = Set(within = model.N * model.S * model.D,initialize = [(n,s,d) for n in model.N for s in model.S for d in model.D])

model.x = Var(model.N_S_D,within=Binary)  #,initialize=0)

model.C1 = ConstraintList()
shift_day_combos = [(s,d) for s in model.S for d in model.D]
for s,d in shift_day_combos:
    const_expr = sum(model.x[(n,d)] for n in model.N) == R[(d,s)]
    model.C1.add(expr = const_expr)

# alternate approach...

def cover_requirement(model,d):
    return sum(model.x[n,d] for n in model.N) == R[d,s]

model.C2 = Constraint(model.S,model.D,rule=cover_requirement)

model.pprint()

生成:

...
2 Constraint Declarations
    C1 : Size=6,Index=C1_index,Active=True
        Key : Lower : Body                                                                                                        : Upper : Active
          1 :   1.0 : x[0,D,1] + x[1,1] + x[2,1] + x[3,1] + x[4,1] + x[5,1] + x[6,1] + x[7,1] + x[8,1] + x[9,1] :   1.0 :   True
          2 :   1.0 : x[0,2] + x[1,2] + x[2,2] + x[3,2] + x[4,2] + x[5,2] + x[6,2] + x[7,2] + x[8,2] + x[9,2] :   1.0 :   True
          3 :   2.0 : x[0,3] + x[1,3] + x[2,3] + x[3,3] + x[4,3] + x[5,3] + x[6,3] + x[7,3] + x[8,3] + x[9,3] :   2.0 :   True
          4 :   1.0 : x[0,N,1] :   1.0 :   True
          5 :   1.0 : x[0,2] :   1.0 :   True
          6 :   3.0 : x[0,3] :   3.0 :   True
    C2 : Size=6,Index=C2_index,Active=True
        Key      : Lower : Body                                                                                                        : Upper : Active
        ('D',1) :   1.0 : x[0,1] :   1.0 :   True
        ('D',2) :   1.0 : x[0,2] :   1.0 :   True
        ('D',3) :   2.0 : x[0,3] :   2.0 :   True
        ('N',1] :   1.0 :   True
        ('N',2] :   1.0 :   True
        ('N',3) :   3.0 : x[0,3] :   3.0 :   True

11 Declarations: N S D N_S_D_domain_index_0 N_S_D_domain N_S_D x C1_index C1 C2_index C2