8.6 Stopping the solver¶
Model provides the method
Model.breakSolver that notifies the solver that it must stop as soon as possible. The solver will not terminate momentarily, as it only periodically checks for such notifications. In any case, it will stop as soon as possible. The typical usage pattern of this method would be:
build the optimization model
create a separate thread in which
break the solver by calling
Model.breakSolverfrom the main thread.
Warnings and comments:
It is recommended to use the solver parameters to set or modify standard built-in termination criteria (such as maximal running time, solution tolerances etc.). See Sec. 8.4 (Setting solver parameters).
More complicated user-defined termination criteria can be implemented within a callback function. See Sec. 8.7 (Progress and data callback).
The state of the solver and solution after termination may be undefined.
This operation is very language dependent and particular care must be taken to avoid stalling or other undesired side effects.
8.6.1 Example: Setting a Time Limit¶
For the purpose of the tutorial we will implement a busy-waiting breaker with the time limit as a termination criterion. Note that in practice it would be better just to set the parameter
Suppose we built a model
M that is known to run for quite a long time (in the accompanying example code we create a particular integer program). Then we could create a new thread solving the model:
T = threading.Thread(target=M.solve)
In the main thread we are going to check if one of the two criteria are satisfied:
a time limit has elapsed,
the user pressed
Model.breakSolver we should wait for the solver thread to actually return. Altogether this scenario can be implemented as follows:
T = threading.Thread(target=M.solve) T0 = time.time() try: T.start() # optimization now running in background # Loop until we get a solution or you run out of patience and press # Ctrl-C while True: if not T.is_alive(): print("Solver terminated before anything happened!") break elif time.time() - T0 > timeout: print("Solver terminated due to timeout!") M.breakSolver() break except KeyboardInterrupt: print("Signalling the solver that it can give up now!") M.breakSolver() finally: try: T.join() # wait for the solver to return except: pass