Returning the model in python gurobi interface from a function
AnsweredHello,
I am trying to work on a model after it is created inside a function and returned
Example:
def createmodel(params):
m = Model()
x = m.addVar(vtype = GRB.BINARY)
m.addConstr(constraint)
m.setObjective(objectivefunction)
return m
Next, I create the model using initial params.
model = createmodel(params)
print(model)
Notice that I have return the whole model. Print model gives me following which means, model was returned successfully and correctly.
<gurobi.Model MIP instance Unnamed: 225 constrs, 230 vars>
Next I am trying to change objective of the model. Using model.setObjective(NewParam * x). I get following error. Can anyone help?
name 'x' is not defined'
-
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,
The issue is that the \(\texttt{x}\) variable is only defined in the local scope of the \(\texttt{createmodel()}\) function. This means that you won't be able to access it outside of this function.
Instead, you could return the Model and Var objects together:
def createmodel():
m = Model()
x = m.addVar(vtype=GRB.BINARY)
return m, x
m, x = createmodel()
m.setObjective(x)Alternatively, you could define a separate function that adds variables to your model, then returns the newly created variables.
def addMyVar(m):
return m.addVar(vtype=GRB.BINARY)
model = createmodel()
x = addMyVar(model)
model.setObjective(x)Note that you can always use Model.getVars() to obtain a full list of your model variables. Of course, it's much more convenient to have individual Python variables for each group of model variables.
Thanks,
Eli
0 -
Thank you Eli,
I was able to run the model, however the solution I am getting is different. For example, I am changing only one parameter in the model every iteration, which is in the objective function. Here are two methods that I used.
1) Create new model in every iteration, new variable and the updated parameter
2) Set new objective using setObjective() as you explained above on the model that I created. Just using that new parameter when I update the objective.
I am getting different solutions from these method. Is there anything I am missing?
Amogh
0 -
Hi Amogh,
Could you post a small, self-contained code example that shows the two approaches producing different solutions? That would make it easier to tell what's going on. Thanks!
Eli
0 -
It is difficult to post small example. I ran 6 tests, and 100 iterations maximum in each approaches that give me lower and upper bounds. Out of these, the model was able to obtain exact same upper bound and lower bound before termination in 4 occasions. However, it was able to obtain only lower bound correctly after 100 iterations in other two. My question was, does Gurobi make different choices when solving if I create new variable vs using setObjective().
If this is something that you are not aware of, I will try to see if I can post small code example. However take a look at following code that should help.
Approach 1
def createmodel(param):
m = Model()
x = m.addVar(vtype=GRB.BINARY)
return m, x
m, x = createmodel(param)
for i in range(100):
m.setObjective(f(x and param))
m.optimize()
y = copy(x) # I copy using for loop
obj_value = m.ObjVal
update paramApproach 2
def createmodel(param):
m = Model()
x = m.addVar(vtype=GRB.BINARY)
m.setObjective(f(x and param))
m.optimize()
obj_value = m.ObjVal
return obj_value, x
for i in range(100):
obj, x = createmodel(param)
y = copy(x) # I copy using for loop
update param0 -
Hi Amogh,
Thanks for posting the code snippets. What is the purpose of \(\texttt{y = copy(x)}\) in these loops? You don't ever use \(\texttt{y}\) in these snippets. At any rate, this doesn't add a new variable to the model, and copying Var objects like this isn't supported.
While your two approaches are very similar, they can certainly cause the solver to behave differently.
- With Approach 1, you create a model and variable once, then simply update the objective function at each iteration. In this case, Gurobi may warm-start the solve with the stored solution information from the previous solve. This may change the path Gurobi takes when solving the problem.
- With Approach 2, you create a completely new model and variable at each iteration. Here, Gurobi solves the problem completely from scratch at each iteration.
If you're only making a few changes to the model between solves, I recommend using Approach 1. That said, if both approaches update \(\texttt{param}\) to the same value in each iteration and you make no other changes to the model, the optimal objective values for each approach should match at each iteration.
Does this help? Thanks!
Eli
1 -
Thank you Eli. What I meant by copying variable is just to keep the copy of variable that I use to update the 'param'. I dont actually use copy function. Approach 1 worked very well for me. Thank you
0
Post is closed for comments.
Comments
7 comments