How to define a heuristic callback using JuMP?

I’m trying to implement integer programming callbacks using JuMP. Basically, my heuristic callback is defined like this:

function my_heuristic_callback(cb_data)
x_val = [callback_value(cb_data, x_i) for x_i in x]
x_sol = [v < 0.5 ? 0 : 1 for v in x_val]
status = MOI.submit(
m, MOI.HeuristicSolution(cb_data), x, x_sol
)
println("I submitted a heuristic solution, and the status was: ", status)
end

m = Model(CPLEX.Optimizer)
@variable(m, x[1:n], Bin)
@objective(m, Max, sum(x))
MOI.set(m, MOI.LazyConstraintCallback(), my_lazy_callback)
MOI.set(m, MOI.UserCutCallback(), my_user_callback)
MOI.set(m, MOI.HeuristicCallback(), my_heuristic_callback)
optimize!(m)

The following error appeared:

ERROR: LoadError: MethodError: no method matching submit(::Model, ::MathOptInterface.HeuristicSolution{CPLEX.CallbackContext}, ::Array{VariableRef,1}, ::Array{Int64,1})
Closest candidates are:
  submit(::MathOptInterface.Utilities.MockOptimizer, ::MathOptInterface.AbstractSubmittable, ::Any...) at /Users/user/.julia/packages/MathOptInterface/bygN7/src/Utilities/mockoptimizer.jl:529
  submit(::MathOptInterface.Utilities.CachingOptimizer, ::MathOptInterface.AbstractSubmittable, ::Any...) at /Users/user/.julia/packages/MathOptInterface/bygN7/src/Utilities/cachingoptimizer.jl:727
  submit(::MathOptInterface.Bridges.AbstractBridgeOptimizer, ::MathOptInterface.AbstractSubmittable, ::Any...) at /Users/user/.julia/packages/MathOptInterface/bygN7/src/Bridges/bridge_optimizer.jl:1195

It seems that parameters type are wrong, but the code is a copy-paste from the documentation of JuMP v0.21.3. I don’t know what can possibly be wrong.

The first question is, the, are you using the the version 0.21.3?

If you are not using an environment/project (i.e, have Project.toml and Manifest.toml in your folder) you can just:

julia> import Pkg
julia> Pkg.status()

To check the installed version.

We probably need to relax the signature in CPLEX.jl to accept any real number. Currently, it requires Float64: https://github.com/jump-dev/CPLEX.jl/blob/02d4ef57d143e49c158e59ea14095e84f7916dcd/src/MOI/MOI_callbacks.jl#L207

Just use

x_sol = Float64[v < 0.5 ? 0 : 1 for v in x_val]
1 Like

The vector of values should be Vector{Float64} but you provided Vector{Int}, do

x_sol = [v < 0.5 ? 0.0 : 1.0 for v in x_val]
1 Like

REPL output:

julia> import Pkg
julia> Pkg.status(“JuMP”)
Status ~/.julia/environments/v1.4/Project.toml
[4076af6c] JuMP v0.21.3

Gurobi also gives the same error

Indeed, with gurobi this solution worked. But, with CPLEX shows the following: ERROR: LoadError: CPLEX.CplexError(1003, “CPLEX Error 1003: Bad argument to Callable Library routine.\n”). But it may ocur because i’m sending infeasible integer points.

Upgrade CPLEX to 12.9 or 12.10. I think there was a bug in 12.8 with the callbacks.

TY Sir :smiley: cplex 12.10 works like a charm

1 Like