Skip to main content

Solving to optimal within a timelimit, after which terminating at a feasible solution in gurobipy using callbacks

Answered

Comments

3 comments

  • Marika Karbstein
    Gurobi Staff Gurobi Staff

    Hi Runqiu,

    As long as you set a time limit that is smaller or equal to 7200 before calling 

    self.m.optimize(callback=stop_at_feasible)

    your callback function is useless. When setting the time limit, the optimization is stopped as soon as the time limit is reached. When terminating during presolve, the progress cannot be saved, and optimization will continue from the beginning when calling optimize again.
    The best option is probably to allow presolve to finish. For this purpose, your callback is needed, and you must remove the time limit. You can stop in your callback when runtime exceeds 7200, regardless of whether a solution was found.

    I hope this helps,
    Marika

    0
  • Runqiu Hu
    Conversationalist
    Curious
    Gurobi-versary

    Hello Marika,

    Thank you for your response. I am not sure whether I follow your idea here, here is my modification:

    • In the non-callback function, set no time limit and call optimize with the callback. After the callback, check whether there is feasible solution found, if not, run optimize with solution limit 1 but still no time limit.
    def optimize(self):
        self.m.setParam('MIPGap', 1e-5)
        self.m.setParam("SolutionLimit", 1e9)
        self.m.optimize(callback=stop_at_feasible)
        # Check if any feasible solution was found within 7200 seconds
        if self.m.SolCount == 0:
           # Reset the TimeLimit and SolutionLimit for the second round of optimization
           self.m.setParam('SolutionLimit', 1)
           self.m.optimize()
    • In the callback function, do model.terminate() if runtime exceeds 7200, i.e.,
    def stop_at_feasible(model, where):
    if where == GRB.Callback.MIP:
    runtime = model.cbGet(GRB.Callback.RUNTIME)
        solcount = model.cbGet(GRB.Callback.MIP_SOLCNT)
        if runtime >= 7200:
          model.terminate()  # terminate the current optimization process

    Am I right here? Then why would this prevent the optimization from starting again? I guess the major difference here is using "terminate() to stop after runtime reached in callback" vs "stop by timelimit parameter"?

    Hope I got it right. Thank you again.

    Regards,
    Runqiu

     

    0
  • Marika Karbstein
    Gurobi Staff Gurobi Staff

    Hi Runqiu,

    No, the difference is that your callback does not do anything during presolve. Because you have

    if where == GRB.Callback.MIP:

    Hence, presolve is completed and not interrupted because of a time limit.
    The problem is that the "current status" of the model cannot be saved when terminating during presolve. So, the presolve starts again when calling optimize again.

    Best regards,
    Marika

    0

Please sign in to leave a comment.