0

I'm new to Gurobi and Python in general, and keep getting the error code 'KeyError: 0' on line 27 (which is the final line) whenever I run my code (which obviously isn't complete but my professor encouraged us to run our code as we write it because it's easier to troubleshoot that way).

I've read on multiple forums what that means (that it tried to access key '0' value from the dictionary where the key isn't present in that dictionary (or) which isn't initialized), but still don't really understand it?

from gurobipy import *

# Sets
SetA = ["a", "b", "c", "d", "e"]
SetB = ["f", "g", "h", "i", "j",
   "k", "l", "m", "n", "o"]

A = range(len(SetA))
B = range(len(SetB))

# Data
PC = 100
X = [1, 2, 3, 4, 5]
D = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Y = [
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
[21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
[31, 32, 33, 34, 35, 36, 37, 38, 39, 40],
[41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
]

m = Model("Problem 2")

# Variables
Z = {(a,b): m.addVar() for a in A for b in B}

# Objective
m.setObjective(quicksum((PC+X[a]+Y[a][b])*Z[a][b] for a in A for b in B), GRB.MINIMIZE)
Ruby Pa
  • 109
  • 2
  • For basic understanding of it, see this: [KeyError](https://stackoverflow.com/questions/10116518/im-getting-key-error-in-python). – Mayank Porwal Mar 30 '20 at 13:21
  • Does this answer your question? [I'm getting Key error in python](https://stackoverflow.com/questions/10116518/im-getting-key-error-in-python) – Mayank Porwal Mar 30 '20 at 13:22
  • @MayankPorwal No because I thought that the 0th key does exist in my code? – Ruby Pa Mar 30 '20 at 13:24
  • 2
    Your indexing of `Z` is inconsistent with how it was created. It was created as a flat dict using 2-element tuples as keys, e.g. `Z[(1, 2)]`. But it is being accessed as nested lists (or dicts), e.g. `Z[1][2]`. Pick one of the two, and use it consistently. – Tom Karzes Mar 30 '20 at 13:27
  • `{(a,b): f"{a} {b}" for a in range(2) for b in range(4)}` --> `{(0, 0): '0 0', (0, 1): '0 1', (0, 2): '0 2', (0, 3): '0 3', (1, 0): '1 0', (1, 1): '1 1', (1, 2): '1 2', (1, 3): '1 3'}` This works. The error is in `m.addVar()` but you haven't provided the source for it. – Tin Nguyen Mar 30 '20 at 13:28
  • @TomKarzes Ohhh okay - changing in the final line the Z[a][b] to Z[a,b] no longer gives me the error code. Thank you! – Ruby Pa Mar 30 '20 at 13:33
  • Note that you could use the [Model.addVars()](https://www.gurobi.com/documentation/9.0/refman/py_model_addvars.html) method to create the Z variables more succinctly. This method returns a [tupledict](https://www.gurobi.com/documentation/9.0/refman/py_tupledict.html) (a sub-class of the standard Python dict) indexed by the arguments you provide. In your case, this would be done with `Z = m.addVars(A, B)`. – Eli Towle Mar 30 '20 at 23:51

2 Answers2

0

Solution:

Change final line to:

 m.setObjective(quicksum((PC+X[a]+Y[a][b])*Z[a,b] for a in A for b in B), GRB.MINIMIZE)
Ruby Pa
  • 109
  • 2
0

You are getting keyerror 0 because at the beginning of your list comprehension, where

for a in A

a is equal to 0, so at this line

m.setObjective(quicksum((PC+X[a]+Y[a][b])*Z[a][b] for a in A for b in B), GRB.MINIMIZE)

where you typed Z[a][b], you are trying to access the value of key 0 of dictionary Z (and then again key 0 of dictionary Z[a], which does not even exists), but in dictionary Z there is no key 0, since all your keys are tuples.

So as you correctly derived yourself, you don't want to access a value stored in key b of dictionary Z[a], instead you want to access the value stored in key (a, b) of dictionary Z, so

m.setObjective(quicksum((PC+X[a]+Y[a][b])*Z[a,b] for a in A for b in B), GRB.MINIMIZE)
Tms91
  • 3,456
  • 6
  • 40
  • 74