JuMP/CPLEX: how to set heuristic solution using SparseAxisArrays in callback

Dear folks,
unfortunately I fail to submit a heuristic solution using SparseAxisArrays in a callback. Here is an MWE:

using JuMP, CPLEX

model = JuMP.direct_model( CPLEX.Optimizer() )
set_optimizer_attribute( model, "CPXPARAM_Threads", 1 )
@variable( model, x[i=1:2, j=i:2], Bin )
@variable( model, y[i=1:2, j=i:2], Bin )
@objective( model, Max, sum(x) + sum(y) )
@constraint( model, sum(x) + sum(y) <= 5 )


function mycallback( cb_data::CPLEX.CallbackContext, context_id::Clong )
    if context_id == CPX_CALLBACKCONTEXT_CANDIDATE
        ispoint_p = Ref{Cint}()
        ret = CPXcallbackcandidateispoint(cb_data, ispoint_p)
        if ret != 0 || ispoint_p[] == 0
            return  # No candidate point available or error
        end

        #get values
        CPLEX.load_callback_variable_primal(cb_data, context_id)
        xvals = callback_value.( Ref(cb_data), model[:x] ) #NOTE: type of xvals, yvals is JuMP.Containers.SparseAxisArray{Float64,2,Tuple{Int64,Int64}}
        yvals = callback_value.( Ref(cb_data), model[:y] )

        #set values
        xvals[1,1] = 0.0
        xvals[1,2] = xvals[2,2] = 1.0
        yvals[1,1] = yvals[1,2] = yvals[2,2] = 1.0

        #submit
        vars = [model[:x], model[:y]]
        vals = [xvals, yvals]
        status = MOI.submit( model, MOI.HeuristicSolution(cb_data), vars, vals )
        println("status: $status")
    end

    return
end
MOI.set(model, CPLEX.CallbackFunction(), mycallback)
optimize!( model )

where line status = MOI.submit( model, MOI.HeuristicSolution(cb_data), vars, vals ) yields

LoadError: MethodError: no method matching submit(::Model, ::MathOptInterface.HeuristicSolution{CPLEX.CallbackContext}, ::Array{JuMP.Containers.SparseAxisArray{VariableRef,2,Tuple{Int64,Int64}},1}, ::Array{JuMP.Containers.SparseAxisArray{Float64,2,Tuple{Int64,Int64}},1})
Closest candidates are:
  submit(::MathOptInterface.Utilities.MockOptimizer, ::MathOptInterface.AbstractSubmittable, ::Any...) at /home/user/.julia/packages/MathOptInterface/ZJFKw/src/Utilities/mockoptimizer.jl:529
  submit(::MathOptInterface.Utilities.CachingOptimizer, ::MathOptInterface.AbstractSubmittable, ::Any...) at /home/user/.julia/packages/MathOptInterface/ZJFKw/src/Utilities/cachingoptimizer.jl:764
  submit(::MathOptInterface.Bridges.AbstractBridgeOptimizer, ::MathOptInterface.AbstractSubmittable, ::Any...) at /home/user/.julia/packages/MathOptInterface/ZJFKw/src/Bridges/bridge_optimizer.jl:1272

Do you have any suggestions what went wrong? Many thanks in advance.

Docs: https://jump.dev/JuMP.jl/stable/callbacks/#Heuristic-solutions

You need to submit a vector of variables, and a vector of values.

Use something like:

julia> vars = vcat(
           [model[:x][i, j] for i = 1:2 for j = i:2],
           [model[:y][i, j] for i = 1:2 for j = i:2]
       )
6-element Array{VariableRef,1}:
 x[1,1]
 x[1,2]
 x[2,2]
 y[1,1]
 y[1,2]
 y[2,2]
1 Like

Great it works, thank you!!

1 Like