Skip to main content

KeyError 10 in Constraint line of Python code; MCLP Optimization model building

Answered

Comments

6 comments

  • Jaromił Najman
    • Gurobi Staff

    Could you please add to your code, how you define \(\texttt{num_customers}\) and \(\texttt{cartesian_prod}\)?

    1
  • Tanmoy Das
    • Gurobi-versary
    • Investigator
    • Collaborator

    num_facilities = len(facilities)
    num_customers = len(customers)
    cartesian_prod = list(product(range(num_customers), range(num_facilities)))

    0
  • Jaromił Najman
    • Gurobi Staff

    You are constructing your cartesian product over num_customers x num_facilities. In your constraint you access it via c,f in cartesian_prod, i.e., f is from num_facilities. But you constructed select over num_customers, thus you get a key error. You could try either adjusting your cartesian_prod list or how you construct the constraint.

    cartesian_prod = list(itertools.product(range(num_facilities),range(num_customers)))

    or

    constrain1 = model1.addConstrs((assign[f,c] >= select[f] for f,c in cartesian_prod), name='Constraint1')

    Best regards, 
    Jaromił

    0
  • Tanmoy Das
    • Gurobi-versary
    • Investigator
    • Collaborator

    Revised formulation below:

    # MIP model formulation
    model1 = gp.Model('MCLP v1')
    # Decision variables
    cover = model1.addVars(pairings, vtype=GRB.BINARY, name='Cover')
    select = model1.addVars(num_facilities, vtype=GRB.BINARY, name='Select')
    # Objective function
    objective1 = gp.quicksum(cover[c, f]*demand[c] for c,f in pairings)
    model1.setObjective(objective1, GRB.MAXIMIZE)
    # Constraints
    c1 = model1.addConstrs((cover[c,f] <= select[f] for c,f in pairings), name='c1')
    c2 = model1.addConstr((gp.quicksum(select[f] for f in range(num_facilities)) == T_maxStations), name='c2')
    #c3 = model1.addConstrs((cover.sum(c,'*') == 1 for c in range(num_customers)), name='c3')
    model1.write('Outputs/model1.lp')
    model1.optimize()

    I got the following output where each c is covered twice. I need c to be covered only once. Constraint c3 (commented in current code) would to the job, but, c3 makes model1 infeasible. 

    ['cover',
     MultiIndex([(0, 14),
                 (0, 15),
                 (2, 14),
                 (2, 15),
                 (3, 14),
                 (3, 15),
                 (4, 14),
                 (4, 15),
                 (5, 14),
                 (5, 15),
                 (6, 14),
                 (6, 15),
                 (9, 14),
                 (9, 15)],
                ),
     'select',
     Int64Index([14, 15], dtype='int64')]

     

    Expected output is something like below:

    ['cover',
     MultiIndex([(0, 14),
                 (2, 14),
                 (3, 15),
                 (4, 14),
                 (5, 15),
                 (6, 15),
                 (9, 14),,
                ),
     'select',
     Int64Index([14, 15], dtype='int64')]

    I think index in Constraint1 in this Python implementation is NOT accurately reflecting the math model.

    0
  • Jaromił Najman
    • Gurobi Staff

    The example you provided is not a minimal reproducible example. There are definitions missing, e.g., pairings, num_facilities, demand.

    Did you analyze the LP file you write to \(\texttt{Output/model1.lp}\)? Maybe you can spot some mistake in there. It might be useful to reduce the size of your model when analyzing the LP file.

    0
  • Tanmoy Das
    • Gurobi-versary
    • Investigator
    • Collaborator

    Hello Jaromil,

    I will keep your suggestions in mind. 
    I solved the conflict of C1 & C3 by changing comparison operator == into <= in C3 

    model1.addConstrs((cover.sum(c,'*') <= 1 for c in range(num_customers)), name='c3')

    0

Please sign in to leave a comment.