Keyerror in objective function
AnsweredCurrently I'm trying to solve my fist optimization problem with Gurobi, however I encountered the following keyerror after adding the objective function to the model:
KeyError: ((0.0, 0.0, 0.0), 0)
The objective function is:
m.setObjective(quicksum(costs[combo]*X[combo,t]
for combo in proc_combo
for t in time_points), GRB.MINIMIZE)
The X variables are defined in the following way:
X = m.addVars(proc_combo, hours, vtype=GRB.BINARY, name='X')
And the proc_combo and costs are defined in the following multidict:
proc_combo, costs = multidict({
(0.0, 0.0, 0.0): 91117.64,
(0.0, 1.0, 1.0): 28000.0,
(1.0, 1.0, 1.0): 12000.0,
(0.0, 2.0, 2.0): 38.97,
(0.0, 4.0, 3.0): 589.52,
(0.0, 5.0, 4.0): 50.0,
(0.0, 6.0, 5.0): 825.32,
(0.0, 7.0, 6.0): 7640.56,
(1.0, 7.0, 6.0): 3780.0,
(2.0, 7.0, 6.0): 5572.27})
Lastly, hours is a list with integers, such as:
hours = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
I guess the error has something to do with combing a tuple with an integer. However, this did not result to an error when creating the X variables. Has anybody a suggestion how to fix this?
-
You define variable \(X\) over the tuples in \(\texttt{proc_combo}\)\(\times\)\(\texttt{hours}\). Thus, you can access the tupledict returned by the addVars method via, e.g.,
print(X[0.0, 0.0, 0.0 ,0])
print(X[0.0, 1.0, 1.0 ,0])
print(X[1.0, 1.0, 1.0 ,0])
# etcHowever, what you are trying is to access the \(X\) variables via a tuple from the \(\texttt{proc_combo}\) dictionary and an entry from \(\texttt{hours}\). In other words, what you are trying to do is
print(X[(0.0, 0.0, 0.0) ,0])
print(X[(0.0, 1.0, 1.0) ,0])
print(X[(1.0, 1.0, 1.0) ,0])which does not work. To make it work, you have to unpack the tuple via the \(\texttt{*}\) operator
m.setObjective(quicksum(costs[combo]*X[(*combo),t]
for combo in proc_combo
for t in time_points), GRB.MINIMIZE)Best regards,
Jaromił0 -
Thank you for your quick explanation, it solved the problem!
0 -
If you don't mind, I have a additional question.
As can be seen before, the X variables have four subsets. In my objective function I want to sum all the X variables together, with an exclusion of the X variables in where the first subset is 3, so:

Until now, I've only managed to sum all X variables with:
m.addConstr((quicksum(X) <= n ), 'name')
Is there a way to exclude these specific variables from the summation?
0 -
Yes, it is possible. You can use \(\texttt{for}\)-loops and \(\texttt{if}\)-clauses within the \(\texttt{quicksum}\) when constructing the list of variables. In your case, something like the following should work
m.addConstr((quicksum(X[p,j,k,t] for p in P if p != 3
for j in J[p]
for k in K[p]
for t in T) <= n ), 'name')0
Please sign in to leave a comment.
Comments
4 comments