Stop JuMP optimization when gap doesn't improve enough

Suppose that I have a time limit of one day with JuMP and CPLEX:

using JuMP, CPLEX, Dates

set_optimizer_attributes(model, "CPX_PARAM_TILIM" => Dates.value(Second(Day(1))) # CPU limit in seconds

Can I also have another time limit, let us say n hours, for instance 2 hours such that, if the gap doesn’t improve enough for 2 hours, the model stops? Suppose that the gap only improves from 6.069% to 6.061% during 2 hours (less than a percent), can I make my model JuMP model stop?

If that is not possible, is there a way to stop the model if the gap stays constant for let us say 20 minutes? i.e. both the incumbent and the best bound doesn’t improve for 20 minutes.

Thank you!

You can probably achieve this with the CPLEX callbacks.

I do not know if there is a “direct” method for doing this, but you can terminate the solving process in a callback with:

ret = CPXcallbackabort( cb_data )

You can access information in the callback with, for instance:

#float infos
function cpx_callbackgetinfodbl( cb_data::CPLEX.CallbackContext, what )
    data_p = Ref{Cdouble}()
    ret = CPXcallbackgetinfodbl(cb_data, what, data_p)

    if ret != 0
        @warn "error retrieving $what"
    end
    return data_p[]::Float64
end

#compute mip gap in %
function cpx_callbackget_mip_gap( cb_data::CPLEX.CallbackContext )
    best_bnd::Float64   = cpx_callbackgetinfodbl( cb_data, CPLEX.CPXCALLBACKINFO_BEST_BND )
    best_sol::Float64   = cpx_callbackgetinfodbl( cb_data, CPLEX.CPXCALLBACKINFO_BEST_SOL )
    mip_gap::Float64    = ((best_bnd - best_sol) / (0.0000000001 + best_sol)) * 100
    return mip_gap::Float64
end

Then use your favorit stopping criteria and abort solving. See also the example of a solver-specific callback.

1 Like