# Stop JuMP optimization when gap doesn't improve enough

**URL:** <https://discourse.julialang.org/t/stop-jump-optimization-when-gap-doesnt-improve-enough/109437>\
**Category:** Optimization (Mathematical)\
**Tags:** jump\
**Created:** [January 30, 2024, 9:22am UTC](https://discourse.julialang.org/t/stop-jump-optimization-when-gap-doesnt-improve-enough/109437 "2024-01-30T09:22:48Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![K5Julien](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/k5julien/32/210626_2.png) [@K5Julien](https://discourse.julialang.org/u/K5Julien)\
**Post date:** [January 30, 2024, 9:22am UTC](https://discourse.julialang.org/t/stop-jump-optimization-when-gap-doesnt-improve-enough/109437/1 "2024-01-30T09:22:48Z")

</div>

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

```julia
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!

---

<div class="post-metadata">

**Author:** ![blegat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/blegat/32/217090_2.png) [@blegat](https://discourse.julialang.org/u/blegat)\
**Post date:** [January 30, 2024, 10:40am UTC](https://discourse.julialang.org/t/stop-jump-optimization-when-gap-doesnt-improve-enough/109437/2 "2024-01-30T10:40:34Z")

</div>

You can probably achieve this with the [CPLEX callbacks](https://github.com/jump-dev/CPLEX.jl?tab=readme-ov-file#callbacks).

---

<div class="post-metadata">

**Author:** ![mike\_k](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike_k/32/211864_2.png) [@mike\_k](https://discourse.julialang.org/u/mike_k)\
**Post date:** [January 30, 2024, 10:45am UTC](https://discourse.julialang.org/t/stop-jump-optimization-when-gap-doesnt-improve-enough/109437/3 "2024-01-30T10:45:38Z")

</div>

I do not know if there is a “direct” method for doing this, but you can terminate the solving process in a [callback](https://www.ibm.com/docs/en/icos/22.1.1?topic=manual-callback-context) with:

```julia
ret = CPXcallbackabort( cb_data )

```

You can access [information](https://www.ibm.com/docs/en/icos/22.1.1?topic=manual-cpxcallbackinfo) in the callback with, for instance:

```julia
#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](https://github.com/jump-dev/CPLEX.jl?tab=readme-ov-file#callbacks).
