KeyError 10 in Constraint line of Python code; MCLP Optimization model building
AnsweredI am trying to implement a constraint of the maximal coverage problem (Equation 16.2 from the image at the bottom of this post). A minimal Python code is below.
But the code is giving me error KeyError: 10 in Constraint1 (bold line in the code). Explanation of Keyerror seems like certain index values might not exist. I check my data, all index values iterating c,f are available in cartesian_prod.
model1 = gp.Model('facility_location')
select = model1.addVars(num_customers, vtype=GRB.BINARY, name='Select')
assign = model1.addVars(cartesian_prod, ub=1, vtype=GRB.CONTINUOUS, name='Assign')
constrain1 = model1.addConstrs((assign[c,f] >= select[f] for c,f in cartesian_prod), name='Constraint1')

-
Official comment
This post is more than two years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum, or try Gurobot, our chatbot interface offering instant, expert-level support. -
Could you please add to your code, how you define \(\texttt{num_customers}\) and \(\texttt{cartesian_prod}\)?
1 -
num_facilities = len(facilities)
num_customers = len(customers)
cartesian_prod = list(product(range(num_customers), range(num_facilities)))0 -
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 -
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 -
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 -
Hello Jaromil,
I will keep your suggestions in mind.
I solved the conflict of C1 & C3 by changing comparison operator == into <= in C3model1.addConstrs((cover.sum(c,'*') <= 1 for c in range(num_customers)), name='c3')
0
Post is closed for comments.
Comments
7 comments