Retrieving Objective Bound via Callback doesn't match Model.ObjBound
AnsweredI'm not too clear of the inner workings of Gurobi, but i'm trying to extract the Objective Bound specifically the lower bound of the primal problem.
This can be easily done with `model.ObjBound`, however in my particular case, i'm looking to extract this value along with the objective value and runtime during the gurobi callback. I'm unsure where the value of this Objective Bound should be extracted, but i extracted it via checking MIPSOL:
def gurobi_callback(model, where, *, cbdata: CallBackData, logfile: PrimalIntegralLog
) -> None:
"""
Callback function. 'model' and 'where' arguments are passed by gurobipy
when the callback is invoked. The other arguments must be provided via
functools.partial:
1) 'cbdata' is an instance of CallbackData, which holds the model
variables and tracks state information across calls to the callback.
2) 'logfile' is a writeable file handle.
"""
if model.ModelSense == GRB.MAXIMIZE:
raise ValueError(
"Gurobi model should have already been a minimization problem "
"using the get_minimization_grb_model within grb_utils.py."
)
if where == GRB.Callback.MIPSOL:
obj = model.cbGet(GRB.Callback.MIPSOL_OBJBST)
runtime = model.cbGet(GRB.Callback.RUNTIME)
obj_bound = model.cbGet(GRB.Callback.MIPSOL_OBJBND)
logfile.add(obj, runtime, obj_bound)
within my logfile.add() function, i will deal with whether or not i will add the `obj` (objective value) or `obj_bound` (objective bound). Particularly, i will append the `obj` if the `obj` is better (lower) and `obj_bound` if it it increases (dual is a maximization problem). However, after storing and saving my values to a dataframe, i notice that even though my gurobi solves to optimality, my `obj_bound` value is not close to optimality.
What's worst is that when i print out the model.ObjBound after using .optimize(), the value is also different. The model.ObjBound returns the expected value that is the same value (or very close to) the optimal objective value, but the one extracted from the callback function turns out to be higher than the optimal objective value - How can this be possible?
Should i just add an additional line to check if obj_bound>obj, then obj_bound = obj? and if so then my logfile.add() willl add the obj_bound that's equivalent to the objective value?
Please help!
-
Hi Moses,
If the primal problem is a minimization model, the current best objective values and the current best objective bound queried via the MIPSOL callback will always show a non-increasing and a non-decreasing trend, respectively. Furthermore, the MIPSOL_OBJBST value will always be greater than the MIPSOL_OBJBND.
The MIPSOL callback is only called once a new solution is found. Therefore, it is expected that the last MIPSOL_OBJBND might not equal to the final optimal objective value because further node exploration might be required to prove optimality. To have the OBJBST equal to the ObjBound, you need to query this value in MIPNODE callback which is called at each node of the search tree.
Best regards,
Maliheh
0
Please sign in to leave a comment.
Comments
1 comment