Skip to main content

Callback Setsolution from a MIP solution node

Answered

Comments

11 comments

  • Pirmin
    Gurobi-versary
    First Comment

    I am facing the same issue.

    Is there any solution for that?

    1
  • Eli Towle
    Gurobi Staff Gurobi Staff

    In the next major or minor Gurobi release, you will be able to set solutions from the \( \texttt{MIPSOL} \) callback. In the meantime, a workaround is to store the solution, then pass it to Gurobi in the next \( \texttt{MIPNODE} \) callback.

    1
  • Eli Towle
    Gurobi Staff Gurobi Staff

    You can generate and store the solution when \( \texttt{mycallback} \) is called with \( \texttt{where=MIPSOL} \), then set the solution the next time \( \texttt{mycallback} \) is called with \( \texttt{where=MIPNODE} \). So the solution is generated and set in two different calls to \( \texttt{mycallback} \). E.g.:

    def mycallback(model, where):
    if where == GRB.Callback.MIPSOL:
    vals = model.cbGetSolution(model._vars)
    model._vals = [v / (v + 3) for v in vals]
    elif where == GRB.Callback.MIPNODE and model._vals is not None:
    model.cbSetSolution(model._vars, model._vals)
    model._vals = None


    model._vars = model.getVars()
    model._vals = None
    model.optimize(mycallback)
    1
  • Jose Alexander Vindel Garduno
    Collaborator
    Investigator
    Gurobi-versary

    Hello, I am facing the same question, the only thing I could find cb.GetNodeRel() can be used to retrieve the variables of the relaxation but I am unsure if it actually works for you, would be helpful if someone could share how can this be solved

    0
  • Jose Alexander Vindel Garduno
    Collaborator
    Investigator
    Gurobi-versary

    How can you have two callbacks in one function? to my understanding once you set the first \( \texttt{if} \) block, that's the only one it gets to run:

    def mycallback(model, where):
    if where == GRB.Callback.MIPSOL:
    v = model.cbGetSolution(model._vars)
    vs = model._vars
    vi = v/(v+3)
    elif where == GRB.Callback.MIPNODE:
    model.cbLazy(lhs,sense,rhs)
    model.cbSetSolution(vs,vi)

    model.optimize(mycallback)
    0
  • Philip Taffet
    Gurobi-versary
    Conversationalist
    Curious

    Your callback can definitely handle multiple `where` values with if statements.

    0
  • Jose Alexander Vindel Garduno
    Collaborator
    Investigator
    Gurobi-versary

    Thanks a lot! I am trying to implement this in the model I am working on, when I tried to use \( \texttt{where=MIPNODE} \) nothing seemed to happen, then I checked for the condition to see if it's being read, if the statement is true then the block inside that \(\texttt{elif}\) will be executed

    print(str(where==GRB.Callback.MIPNODE))

    However, the result I get back is 

    False

    So,  

    model.cbSetSolution(vars, solution)

    won't get executed, my question is, what could make the \(\texttt{GRB.Callback.MIPNODE}\) false? 

    0
  • Eli Towle
    Gurobi Staff Gurobi Staff

    Note that \( \texttt{where} \) is equal to \( \texttt{GRB.Callback.MIPSOL} \) when the solution is set, then \( \texttt{mycallback} \) will be called later (separately) with a \( \texttt{where} \) value of \( \texttt{GRB.Callback.MIPNODE} \). \( \texttt{where==GRB.Callback.MIPNODE} \) is \( \texttt{false} \) whenever \( \texttt{mycallback} \) is called with a non-\( \texttt{MIPNODE} \) value of \( \texttt{where} \) (see the Callback Codes section of the documentation). 

    Is \( \texttt{mycallback} \) never called with \( \texttt{where==GRB.Callback.MIPNODE} \)? It would be helpful to see the log output from Gurobi and your code for a minimal working callback function.

    0
  • Hello, 

    Thanks, I could see what I was doing wrong. Now my code enters \( \texttt{where=MIPNODE} \) and I can make use of \(\texttt{cb.SetSolution}\). However, I also want to use \(\texttt{Model.UseSolution()}\), and when printing to check what value I am about to pass I get 1e+100. What does this value mean and what kind of heuristic does gurobi implement at this point?

    0
  • Eli Towle
    Gurobi Staff Gurobi Staff

    The return value of Model.cbUseSolution() is \( \texttt{GRB.INFINITY} \) (1e+100) if Gurobi isn't able to compute an improved solution using the variable values specified in Model.cbSetSolution(). Are you sure your solution is feasible and better than the current incumbent objective value?

    Gurobi solves an optimization problem to try to "fill in" any missing variable values. The solution you give to Gurobi generally comes from your own heuristic algorithm.

    0
  • Maliheh Aramon
    Gurobi Staff Gurobi Staff

    Hi Everyone

    Gurobi 9.5 was recently released. Included in this release is the ability to set a new solution from the MIP and the MIPSOL callbacks. Therefore, there is no need to store a solution internally and wait for the next MIPNODE callback anymore.

    Unfortunately, this new feature is missing in the Gurobi 9.5 documentation. It will be added in the next technical release. 

    We hope this new feature works well for you. Please let us know if you find any issues using this.

    Best regards,

    Maliheh

    0

Please sign in to leave a comment.