Hide navigation sidebar
Hide table of contents sidebar
Back to top
Toggle table of contents sidebar

# Callbacks

A callback is a user function that is called periodically by the Gurobi Optimizer in order to allow the user to query or modify the state of the optimization. More precisely, if you pass a function that takes two arguments (`model` and `where`) as the argument to `Model.optimize` or `Model.computeIIS`, your function will be called during the optimization. Your callback function can then call `Model.cbGet` to query the optimizer for details on the state of the optimization.

Gurobi callbacks can be used both to monitor the progress of the optimization and to modify the behavior of the Gurobi Optimizer. A simple user callback function might call `Model.cbGet` to produce a custom display, or perhaps to terminate optimization early (using `Model.terminate`) or to proceed to the next phase of the computation (using `Model.cbProceed`). More sophisticated MIP callbacks might use `Model.cbGetNodeRel` or `Model.cbGetSolution` to retrieve values from the solution to the current node, and then use `Model.cbCut` or `Model.cbLazy` to add a constraint to cut off that solution, or `Model.cbSetSolution` to import a heuristic solution built from that solution. For multi-objective problems, you might use `Model.cbStopOneMultiObj` to interrupt the optimization process of one of the optimization steps in a multi-objective MIP problem without stopping the hierarchical optimization process.

`GRB.Callback` provides a set of constants that are used within the user callback function. The first set of constants provide the options for the `where` argument to the user callback function. The `where` argument indicates from where in the optimization process the user callback is being called. Options are listed in the Callback Codes section of this document.

The other set of constants provide the options for the `what` argument to `Model.cbGet`. The `what` argument is used by the user callback to indicate what piece of status information it would like to retrieve. The full list of options can be found in the Callback Codes section. As with the `where` argument, you refer to a `what` constant through `GRB.Callback`. For example, the simplex objective value would be requested using `GRB.Callback.SPX_OBJVAL`.

When solving a model using multiple threads, the user callback is only ever called from a single thread, so you don’t need to worry about the thread-safety of your callback. However, if the solve was started asynchronously using `Model.optimizeAsync` then the callback is called from the background thread running the optimization. You must make sure that your callback code and foreground code do not interact in a thread-unsafe manner.

A few parameters are callback settable. These parameters can be modified from within a callback invocation by using the `Model.cbSetParam` method.

The following sections provide brief examples of usage of Python functions and class instances as callbacks. You can also look at callback.py and tsp.py for details of how to use Gurobi callbacks from Python.

## Python Functions as Callbacks

The simplest form of a callback is a Python function that takes the `model` and `where` arguments. This allows you to access the callback functions mentioned in the previous section via the `model` argument:

    def callback(model, where):
        if where == GRB.Callback.MIP:
            best_objective = model.cbGet(GRB.Callback.MIP_OBJBST)
            ...

    model.optimize(callback)

Python functions capture variable names from their enclosing scope. This means that if you define your callback function in a scope with access to your model variables, you can use them within your callback:

    model = gp.Model(env=env)

    x = model.addVars(5)
    ...

    def callback(model, where):
        if where == GRB.Callback.MIPSOL:
            solution_values = model.cbGetSolution(x)
            ...

    model.optimize(callback)

This approach fails if you reassign variables from the enclosing scope or otherwise attempt to use them to store data between callback invocations. See Why am I getting an UnboundLocalError when the variable has a value? in the Python documentation for details. If you need to maintain state between callback calls, you should pass an instance of a callable class to `Model.optimize` as described in the next section.

## Python Classes as Callbacks

If your program needs to maintain state data between callback calls, you can use an instance of a callable class to store this state. A class is made callable by implementing a `__call__` method. The `__call__` method must take the `model` and `where` arguments.

For example, the following class would track improvements in the objective with each new solution found during a MIP solve:

    class SolutionCallback:

        def __init__(self):
            self.previous_best_objective = None

        def __call__(self, model, where):
            if where == GRB.Callback.MIPSOL:
                # Query the objective value of the new solution
                best_objective = model.cbGet(GRB.Callback.MIPSOL_OBJ)

                # Check against stored state and report improvement in the
                # (minimization) objective
                if self.previous_best_objective is None:
                    print(f"First solution found with objective: {best_objective}")
                else:
                    improvement = self.previous_best_objective - best_objective
                    print(f"New solution found; improved by {improvement}")

                # Store the current objective for the next call
                self.previous_best_objective = best_objective

    # Use a new instance of SolutionCallback as the callback
    callback = SolutionCallback()
    model.optimize(callback)

## Callbacks in the Tuner

Callbacks can also be used with the tuner. The callback function passed to `Model.tune` must take two positional arguments: `tunercb` and `where`. In contrast to callbacks used for the `Model.optimize` method, the first argument passed to the callback function is a `TunerCb` object, not the `Model` object that started the tuner.

The only functionality available in the tuner callback is to terminate the tuner by calling the `terminate` method of the `TunerCb` object. For example, the following code would stop a tuning run if `should_stop_tuner()` returns `True`:

    def callback(tunercb, where):
        if should_stop_tuner():
            tunercb.terminate()

    model.tune(callback)

Warning

You must not call the `terminate` method of the `Model` object while the tuner is running. This will not stop the tuner and may have unintended effects.

class TunerCb

  Object type passed to the tuner callback. It provides a handle to callback control methods available while the tuning tool is running.

  terminate()

    Generate a request to terminate the current tuning run. This method may only be called from a tuning callback. Note that, in general, the request won’t be acted upon immediately.

Help and Feedback

Press `/` or click to search this documentation | Gurobi website | Gurobi community forum
Go to other Gurobi documentation | Gurobi download | Contact support