Katsu
Katsu

Reputation: 111

Pyomo constraint declaration

begginer to pyomo, I have an issue to code my constraint

Here're my input data:

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

I did the sets declaration like this:

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])

decision variable declaration:

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

constraint declaration whith the constraint being

enter image description here (in my model ˜r is 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)

All cells works fine except the one of the constraint where I get the error: NameError: name 'd' is not defined. Giving this error, I wonder if my set declaration model.N_S_D is correct. Second, I'm not sur on how to declare the set cover requirement (R) and if I sould do it? Thank you

Upvotes: 0

Views: 568

Answers (1)

AirSquid
AirSquid

Reputation: 11938

You have a couple problems in your code.

  • your shifts set doesn't match up. (see mine below)
  • when you see "for each" notation you need to create a constraint for each element of the set or combined sets...the thing you are summing over needs to be inside of the summation expression and you need to loop over the "for eaches" is a good way to think about it... you were flipped, I think.
  • you are not formulating your sum() expression correctly. You need to define the source of the indices in the thing you are summing. I suggest you try some practice problems with sum() on the side -- outside of pyomo to get a better handle on it.
  • In the future, it is more helpful if you paste all of your code in one block in working (or at least error-producing) format so somebody can copy it right out and work on it.

Below are 2 different approaches to your question. First is using your approach with a ConstraintList. The alternate uses a function-Constraint combo, which I find easier, but either works.... Just don't include both as they are redundant. :)

from pyomo.environ import *

S = ['D', 'N'] #shifts
N = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] #employee ID
D = [1, 2, 3] #days
R = {   (1, 'D'): 1,
        (1, 'N'): 1,
        (2, 'D'): 1,
        (2, 'N'): 1,
        (3, 'D'): 2,
        (3, '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, s, d)] for n in model.N) == R[(d, s)]
    model.C1.add(expr = const_expr)

# alternate approach...

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

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

model.pprint()

Generates:

...
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,D,1] + x[2,D,1] + x[3,D,1] + x[4,D,1] + x[5,D,1] + x[6,D,1] + x[7,D,1] + x[8,D,1] + x[9,D,1] :   1.0 :   True
          2 :   1.0 : x[0,D,2] + x[1,D,2] + x[2,D,2] + x[3,D,2] + x[4,D,2] + x[5,D,2] + x[6,D,2] + x[7,D,2] + x[8,D,2] + x[9,D,2] :   1.0 :   True
          3 :   2.0 : x[0,D,3] + x[1,D,3] + x[2,D,3] + x[3,D,3] + x[4,D,3] + x[5,D,3] + x[6,D,3] + x[7,D,3] + x[8,D,3] + x[9,D,3] :   2.0 :   True
          4 :   1.0 : x[0,N,1] + x[1,N,1] + x[2,N,1] + x[3,N,1] + x[4,N,1] + x[5,N,1] + x[6,N,1] + x[7,N,1] + x[8,N,1] + x[9,N,1] :   1.0 :   True
          5 :   1.0 : x[0,N,2] + x[1,N,2] + x[2,N,2] + x[3,N,2] + x[4,N,2] + x[5,N,2] + x[6,N,2] + x[7,N,2] + x[8,N,2] + x[9,N,2] :   1.0 :   True
          6 :   3.0 : x[0,N,3] + x[1,N,3] + x[2,N,3] + x[3,N,3] + x[4,N,3] + x[5,N,3] + x[6,N,3] + x[7,N,3] + x[8,N,3] + x[9,N,3] :   3.0 :   True
    C2 : Size=6, Index=C2_index, Active=True
        Key      : Lower : Body                                                                                                        : Upper : Active
        ('D', 1) :   1.0 : x[0,D,1] + x[1,D,1] + x[2,D,1] + x[3,D,1] + x[4,D,1] + x[5,D,1] + x[6,D,1] + x[7,D,1] + x[8,D,1] + x[9,D,1] :   1.0 :   True
        ('D', 2) :   1.0 : x[0,D,2] + x[1,D,2] + x[2,D,2] + x[3,D,2] + x[4,D,2] + x[5,D,2] + x[6,D,2] + x[7,D,2] + x[8,D,2] + x[9,D,2] :   1.0 :   True
        ('D', 3) :   2.0 : x[0,D,3] + x[1,D,3] + x[2,D,3] + x[3,D,3] + x[4,D,3] + x[5,D,3] + x[6,D,3] + x[7,D,3] + x[8,D,3] + x[9,D,3] :   2.0 :   True
        ('N', 1) :   1.0 : x[0,N,1] + x[1,N,1] + x[2,N,1] + x[3,N,1] + x[4,N,1] + x[5,N,1] + x[6,N,1] + x[7,N,1] + x[8,N,1] + x[9,N,1] :   1.0 :   True
        ('N', 2) :   1.0 : x[0,N,2] + x[1,N,2] + x[2,N,2] + x[3,N,2] + x[4,N,2] + x[5,N,2] + x[6,N,2] + x[7,N,2] + x[8,N,2] + x[9,N,2] :   1.0 :   True
        ('N', 3) :   3.0 : x[0,N,3] + x[1,N,3] + x[2,N,3] + x[3,N,3] + x[4,N,3] + x[5,N,3] + x[6,N,3] + x[7,N,3] + x[8,N,3] + x[9,N,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

Upvotes: 1

Related Questions