Help with Implementation of Branch and Benders Cut in GurobiPy
Awaiting user inputHi
I need to implement following features for solving a MIP
Main goal here is to generate cuts from integral LP solutions to master problem using integer subproblems throughout the tree. My master problem is a Pure Binary problem. When the master problem solution is integer feasible, i.e. all variables take binary values, I know that my subproblems are feasible.
This is what I need to do, at every Node in master problem the LP relaxation is checked. I must solve the master problem to integer optimality before calling the second stage problem: only solve the subproblems when master has an integer solution x ∈ {0,1}.
I am working in python. Can anyone help me with the algorithm? How do I implement this? This is my current code that gives me error when I call
def BendersCallback(model, where):
if where == GRB.Callback.MIPNODE:
if model.cbGet(GRB.Callback.MIPNODE_STATUS) == GRB.OPTIMAL:
x = model.cbGetNodeRel(model._vars)
is this the right approach to begin with? How do I obtain the variable values at the nodes? I am getting the error in the above written as
'gurobipy.Model' object has no attribute '_vars'
How do I resolve this?
-
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,
If you want to only consider integer solutions in your callback, Gurobi has a special "where" value to indicate such cases, i.e., GRB.Callback.MIPSOL, see the callback codes for an overview. Then, you can obtain the current solution with model.cbGetSolution(). There is a short example shown in the method description.
As you can see in this example, the attribute _vars is not set by default, you have to assign your set of variables before you start the optimization process. Then, you can access the variables in the callback. By the way, you can define any attributes for your model and assign any data that you probably need in your callback, see also this example.
Best regards,
Mario0 -
Hi,
I was able to run my model however my solution is not converging at the correct solution to the problem. I am not sure what the reason could be. Before we get into that I had following questions. Currently I am obtaining values of my variable from the master problem in following manner..
for d in range(1,delta+1):
for k in range(1,K+1):
thetaval[(d,k)] = model.cbGetSolution(theta[(d,k)])And to add the lazy cut I am using
model.cbLazy(theta[(d,k)] >= rhs )
My question is what is the difference between above method model.cbGetSolution(theta[(d,k)]) to get the values of master problem vs the method described in the callback.py example @ where = MIPSOL
x = model.cbGetSolution(model._vars)
Is this causing my problem to add incorrect cuts or something?
Amogh
0 -
Hi Amogh,
The only difference between the two usages of cbGetSolution() is that you are using it with a single variable while in the callback.py example all variables are queried at once. Both usages are perfectly fine while it probably could be slightly faster when you query all variables at once.
Your way of adding lazy cuts is fine, too. I cannot see any issues with that.
In my experience, correctly implementing a Benders approach is not trivial, also from a theoretical point of view.
Best regards,
Mario0
Post is closed for comments.
Comments
4 comments