Dear folks,
I use JuMP (v0.21.4) and CPLEX (v0.7.3) and try to get the current variable values of sparse/dense-axis-array variables in a solver-specific callback. A quite long MWE based on the one in the documentation is given below.
Retrieving single values works, however, I then need to create the wanted structures first. After solving is finished the values can be easily obtained by
y_val = value.(model[:y])
z_val = value.(model[:z])
Is there any similar approach for callbacks? Or at least a more efficient (and/or less buggy) approach than the work-around in the example below?
using JuMP, CPLEX, SparseArrays
function my_callback_function(cb_data::CPLEX.CallbackContext, context_id::Clong, model, I, K)
CPLEX.load_callback_variable_primal(cb_data, context_id)
#THIS WORKS
y_val = zeros(Float64, length(I))
for i in I
y_val[i] = callback_value(cb_data, model[:y][i])
end
println("y: $y_val")
z_val = spzeros(Float64, length(I), 5)
for i in I, k in K[i]
z_val[i,k] = callback_value(cb_data, model[:z][i,k])
end
#THIS DOES NOT WORK
# y_val = callback_value.(cb_data, model[:y])
# z_val = callback_value.(cb_data, model[:z])
return
end
function main()
I = 1:2
K = [[1, 4, 5], [2, 3 ,4]]
model = direct_model(CPLEX.Optimizer())
MOI.set(model, MOI.NumberOfThreads(), 1)
@variable(model, y[i in I], Bin)
@variable(model, z[i in I, k in K[i]], Bin)
@constraint(model, sum(y) <= 1)
@objective(model, Max, sum(y) )
function callCallback(cb_data::CPLEX.CallbackContext, context_id::Clong)
if context_id != CPX_CALLBACKCONTEXT_CANDIDATE
return
end
ispoint_p = Ref{Cint}()
ret = CPXcallbackcandidateispoint(cb_data, ispoint_p)
if ret != 0 || ispoint_p[] == 0
return # No candidate point available or error
end
my_callback_function(cb_data, context_id, model, I, K)
return
end
MOI.set(model, CPLEX.CallbackFunction(), callCallback)
optimize!(model)
println("OV: ", objective_value(model) )
#this works
y_val = value.(model[:y])
z_val = value.(model[:z])
return
end
main()
Thanks in advance. Best, mike_k