Search code examples
callbackcplexjulia-jump

Callback - Access constraints matrix coefficients


I am solving integer linear programms with JuMP 0.21.1 and CPLEX. I am using a callback to add user cuts. Inside this callback I would like to access the following information:

  • number of constraints (which varies as I add user cuts);
  • number of variables;
  • value of the coefficients of the constraint matrix;
  • value of the coefficients of the constraints right-hand-side.

I could use global variables to get these information but it would deteriorate the performances as these values are not constant (the number of constraints increases when I add user cuts).

In the JuMP documentation it is specified that the only information I can get is the current value of the variables and that if I need anything else, I must create a solver-dependent callback.

I have seen the GLPK callback in the documentation but it does not really help me. I also found the cplex_callback.jl in the CPLEX.jl github repository which seems promising as there is a function "setcallbackcut" which contains an argument rhs among others. However, I don't know how to use it...

Could you tell me how I could do? Or where I could find examples?


Solution

  • Here is an example of using the solver-dependent callback of CPLEX with user-cuts.

    https://github.com/JuliaOpt/CPLEX.jl/blob/5ae4628446470fa0a46438cdfe577155dbcfd54c/test/MathOptInterface/MOI_callbacks.jl#L336-L366

    Note that CPLEX.jl just wraps CPLEX's C API, so you are limited to what it can do. Here is the documentation: https://www.ibm.com/support/knowledgecenter/SSSA5P_12.10.0/ilog.odms.cplex.help/refcallablelibrary/mipapi/hpMIPcallbacks.html

    In particular, you should be careful with respect to

    number of constraints (which varies as I add user cuts)

    because there is no guarantee that CPLEX will add the cut you provide. Why do you need the coefficients and RHS terms in the callback?

    Note that to avoid using global variables, just wrap everything in a function to create a closure. For example, in the following it is fine to access and modify the variable calls inside the callback.

    function build_and_run_model()
        # ...
        calls = 0
        function my_callback(cb_data, cb_where)
            calls += 1
            # ...
        end
        # ...
    end