Search code examples
setconstraintspyomo

Mathematical modeling from gurobipy to pyomo: How to enumerate over a set in pyomo?


I implemented a course planning problem in gurobipy. It all works well. My next task is to rewrite it in pyomo. I had difficulties with one specific equation (written in gurobipy):

model.addConstrs((quicksum(gamma[l, k, s, T[tau]] for tau in range(index_t, index_t + dur[m]) if tau < len(T))
                      >= dur[m] * start[l, k, s, t] for index_t, t in enumerate(T) for m in M
                      for k in KM[m] for l in LM[m] for s in SM[m]), name='Hintereinander')

gamma[lkst] and start[lkst] are binary decision variables. l,k,s,t are indices where t are periods. So the set T is a list of the periods i have. Here in this equation i need the ord(t) to be able to do the calculations in the sum. Therefore I perform an enumeration(T) at the end of the euqation.(When looping over all needed indices).

My data is given beforehand, so i formulate a ConcreteModel() in pyomo. I have difficulties in including the enumeration of the Set T in pyomo. What I already have:

def gamma_hintereinander_rule(model,m,k,l,s):
    for index_t,t in enumerate(T):
        if k in KM[m]:
            if l in LM[m]: 
                if s in SM[m]: 
                    return sum(model.gamma[l, k, s, T[tau]] for tau in range(index_t, index_t + dur[m]) if tau< len(T)) >= dur[m] * model.start[l, k, s, t]                    
                else:
                    return Constraint.Skip    
            else: 
                return Constraint.Skip
        else:
            return Constraint.Skip
model.gamma_hintereinander = Constraint(M, K, L, S,rule=gamma_hintereinander_rule)

It doesn't work correctly. I'd be really happy and thankful if someone could help me! Best regards! Zeineb


Solution

  • The problem is the for-loop inside of the constraint rule. You are exiting the rule after the first return statement is encountered and so only 1 constraint or Constraint.Skip is returned despite the for-loop. I think the best approach is to index your Constraint by T something like:

    def gamma_hintereinander_rule(model,m,k,l,s,t):
        index_t = T.index(t)
        if k in KM[m]:
            if l in LM[m]: 
                if s in SM[m]: 
                    return sum(model.gamma[l, k, s, T[tau]] for tau in range(index_t, index_t + dur[m]) if tau< len(T)) >= dur[m] * model.start[l, k, s, t]                    
                else:
                    return Constraint.Skip    
            else: 
                return Constraint.Skip
        else:
            return Constraint.Skip 
    model.gamma_hintereinander = Constraint(M, K, L, S, T, rule=gamma_hintereinander_rule)