Callbacks with xpress in JuMP

Hi everyone,

I’m currently working on a MILP problem using the Xpress solver in JuMP. Some instances of this problem are taking considerably longer to solve to optimality, and I would like to implement solver-specific callbacks that dynamically adjust the solver’s runtime/time limit based on the optimality gap. Examples of rules can be:

  • For a 10% gap, allow 10 minutes before terminating if no significant improvement to the objective function is made, with a 9% improvement threshold.
  • For a 5% gap, allow 5 minutes before terminating if no significant improvement is made, with a 4% improvement threshold.
  • For a 1% gap, allow 3 minutes before terminating if no significant improvement is made, with a 0.7% improvement threshold.

I have tried using callbacks but without success. I have read about the use of solver-specific callbacks in Xpress, but I am not entirely sure if this is the best way to achieve my goal. How should I correctly set up these callbacks in JuMP? Are there any examples or code available for such callbacks, or alternative approaches to achieve the same objective?

Thank you for your assistance!

Are there any examples or code available for such callbacks, or alternative approaches to achieve the same objective?

Not yet, and I don’t know how to achieve this without looking into the details.

I’ve opened an issue to look into this: Add callback example to README · Issue #270 · jump-dev/Xpress.jl · GitHub

I’ve opened a PR to update the docs: Add callback example to README by odow · Pull Request #271 · jump-dev/Xpress.jl · GitHub

I guess you want something like this:

using JuMP, Xpress
model = direct_model(Xpress.Optimizer())
start_time, log_times = time(), Any[]
function my_callback_function(cb_data)
    prob = cb_data.model
    p_obj, p_bound = Ref{Cdouble}(), Ref{Cdouble}()
    Xpress.Lib.XPRSgetdblattrib(prob, Xpress.Lib.XPRS_MIPBESTOBJVAL, p_obj)
    Xpress.Lib.XPRSgetdblattrib(prob, Xpress.Lib.XPRS_BESTBOUND, p_bound)
    rel_gap = abs((p_obj[] - p_bound[]) / p_obj[])
    push!(log_times, (time = time() - start_time, gap = rel_gap))
    if log_times[end].gap < 0.1  # or some analysis of the gap
        Xpress.Lib.XPRSinterrupt(cb_data.model, 1234)
    end
    return
end
set_attribute(model, Xpress.CallbackFunction(), my_callback_function)