Usage of variable as key during building of model - Python API
AnsweredI would like to use a "Var" as dictionary key while building a model. The underlying reason is that I would like to use "bidict" while building a model so I can easily reference "Var" when building constraints. But then at the end while retrieving solution I want to easily reference domain objects that "Var" represents when using a solution. Minimal example that describes where the problem is:
import sys
import logging
import time
from gurobipy import *
def main(argv):
try:
d = {}
# Create a new model
m = Model("mip1")
# Create variables
x = m.addVar(vtype=GRB.BINARY, name="x")
y = m.addVar(vtype=GRB.BINARY, name="y")
z = m.addVar(vtype=GRB.BINARY, name="z")
d[x] = "x"
# Set objective
m.setObjective(x + y + 2 * z, GRB.MAXIMIZE)
# Add constraint: x + 2 y + 3 z <= 4
m.addConstr(x + 2 * y + 3 * z <= 4, "c0")
# Add constraint: x + y >= 1
m.addConstr(x + y >= 1, "c1")
m.optimize()
for v in m.getVars():
print('%s %g' % (v.varName, v.x))
print('Obj: %g' % m.objVal)
except GurobiError as e:
logging.exception('Error code ' + str(e.errno) + ": " + str(e))
except AttributeError:
logging.exception('Encountered an attribute error')
if __name__ == "__main__":
logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s',
datefmt='%Y/%m/%d %I:%M:%S %p',
level=(logging.INFO))
logging.Formatter.converter = time.gmtime
main(sys.argv)
The following exception is being thrown:
d[x] = "x"
File "var.pxi", line 39, in gurobipy.Var.__hash__
gurobipy.GurobiError: Variable has not yet been added to the model
Hash value is needed for a Python to accept given object as a dictionary key. And it is not available for variable before calling `update` method.
I was able to get around it by calling "update" before adding it to dictionary but this is sub-optimal strategy and I would prefer to build those dictionaries while I am building model.
import sys
import logging
import time
from gurobipy import *
def main(argv):
try:
d = {}
# Create a new model
m = Model("mip1")
# Create variables
x = m.addVar(vtype=GRB.BINARY, name="x")
y = m.addVar(vtype=GRB.BINARY, name="y")
z = m.addVar(vtype=GRB.BINARY, name="z")
# Set objective
m.setObjective(x + y + 2 * z, GRB.MAXIMIZE)
# Add constraint: x + 2 y + 3 z <= 4
m.addConstr(x + 2 * y + 3 * z <= 4, "c0")
# Add constraint: x + y >= 1
m.addConstr(x + y >= 1, "c1")
m.update()
d[x] = "x"
m.optimize()
for v in m.getVars():
print('%s %g' % (v.varName, v.x))
print('Obj: %g' % m.objVal)
except GurobiError as e:
logging.exception('Error code ' + str(e.errno) + ": " + str(e))
except AttributeError:
logging.exception('Encountered an attribute error')
if __name__ == "__main__":
logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s',
datefmt='%Y/%m/%d %I:%M:%S %p',
level=(logging.INFO))
logging.Formatter.converter = time.gmtime
main(sys.argv)
I would like to ask if and how to do or what is rationale behind not calculating hash values while creating variables.
-
Official comment
This post is more than three 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 why not try our AI Gurobot?. -
Hi Grzegorz,
Unfortunately, in order to access and make use of the variable objects while constructing the your model, you have to call the update function due to Gurobi's lazy update approach.
Is there a particular reason why you would like to use the variable object as key instead of the variable name? You could also just get the variable object by using the getVarByName function.
Best regards,
Jaromił0 -
Hi Jaromił, thanks for finding time to provide an answer. The reason why I want to have bidrectional dictionary is to map business domain objects with variables so it is easier to query solution and then take actions on those objects. Otherwise, I need to use a variable name as a proxy. I ended up with populating regular dictionary in the beginning and then populating bidirectional dictionary after calling update function.
0
Post is closed for comments.
Comments
3 comments