Skip to main content

Callback to print bestbound solution raises errors or does not print

Answered

Comments

3 comments

  • Maliheh Aramon
    • Gurobi Staff Gurobi Staff

    Hi Giordano, 

    The error happens because the function \(\texttt{bbsol}\) does not know what the variable \(\texttt{x}\) is. You need to pass the model variables as data to the callback function. See the callback example implementation for Python and look for the section GRB.Callback.MIPNODE. for the correct implementation of how to use the cbGetNodeRel() method.

    Best regards,

    Maliheh

     

    0
  • Giordano Giambartolomei
    • First Comment
    • First Question

    Thank you for your reply, if I understand correctly, since I set two list of variables for the model,

    s = [m.addVar(lb = 0.0, ub = 1.0, name = "s" + str(i)) for i in range(n)]
    b = [m.addVar(lb = 0.0, ub = 1.0, name = "b" + str(i)) for i in range(n)]

    I should use

    print(model.cbGetNodeRel(s))

    print(model.cbGetNodeRel(b))

    I tried and it does work now. However, I noticed that evaluating the objective on [s, b] does not return the bestbound on the objective reported at termination, which is 0.9986500364875883 and coincides with the bound I can also check at the MIPNODE by adding print(model.cbGet(GRB.Callback.MIPNODE_OBJBND)) to the callback. Instead evaluating at [s,b] returns somehow a slightly better bound: 0.9747766007192235. In this model n=16 and the function is well-behaved, I do not think this could be due to truncation error, it seems that [s,b] is genuinely not the same solution of the best bound (and it is neither the solution for the optimal objective). I read in a related question it could be due to some additional work made by the optimizer on other Threads than the callback one, yet this persists, with a slightly different value, even after setting

    m.Params.Threads = 1

    Since the difference between the two values is quite large, is there a way to get a more accurate solution for the best bound? Did I perhaps implement model.cbGetNodeRel wrong again?

    0
  • Maliheh Aramon
    • Gurobi Staff Gurobi Staff

    Do you solve the model to optimality? The best bound solution at optimality is equal to the optimal solution. I am not sure why you need to look at the node solution at optimality. 

    The best bound does not necessarily come from nodes solved to optimality. It might come from partially explored nodes and global improvements that are not tied to any specific node. 

    Let us assume at a given time, the incumbent is 0.99 and the best bound is 0.97 and there is only one node left to explore. The Gurobi optimizer might not solve the relaxation to optimality as soon as it can prove that its solution cannot be lower than than 0.99. It would then terminate with CUTOFF status. In this example, the best bound solution retrieved via MIPNode will not necessarily have an equal objective value to the model optimal objective value.

    Best regards,
    Maliheh 

    0

Please sign in to leave a comment.