Dear All,
I am experimenting with JuMP callback with Gurobi’s MIQCP feature, where I am storing the heuristic values based on tips from https://discourse.julialang.org/t/jump-cplex-how-to-set-heuristic-solution-using-sparseaxisarrays-in-callback/56938. However, I see a Dimension mismatch
while setting my variables to heuristic values.
using Gurobi, JuMP
const GRB_ENV = Gurobi.Env()
model = direct_model(Gurobi.Optimizer(GRB_ENV))
set_optimizer_attribute(model, "NonConvex", 2)
# "NonConvex" => 2 tells Gurobi to use its nonconvex algorithm
# declare the variables
# ----------------------------
@variable(model, x[1:2] >= 0)
@variable(model, y >= 0)
@variable(model, z >=0)
@variable(model, M[1:3,1:3], Symmetric)
# add constraints
# --------------------
@constraint(model, x[1] + x[2] + y + z <= 10)
@constraint(model, x[1]*y + x[2]*z <= 1)
@constraint(model, x[1]*z + x[2]*y == 1)
# add objective
# -----------------
@objective(model, Min, x[1] + x[2])
# this is the callback function to implement the heuristic solution
# -----------------------------------------------------------------------------
function my_heuristic_callback_function(cb_data)
# load the current values of the variables at a node of the branch-and-bound tree
x_val = callback_value.(cb_data, x)
y_val = callback_value.(cb_data, y)
z_val = callback_value.(cb_data, z)
heuristic_flag = 0
# println(α_val)
if abs(x_val[2]) <= 1e-4 # this is the condition for applying the heuristic
@info "[🐼 ] Heuristic condition satisfied: Status of the callback node is: $(callback_node_status(cb_data, model))" # show the status of the callback node
@info "[🎤 ] The values of the variables at the callback node $([x_val; y_val; z_val])"
x_heuristic = [0.10102051067754236; 0.0]
y_heuristic = 0.0
z_heuristic = 9.898979489322459
M_heuristic = [0 for i in 1:3, j in 1:3]
# Load the JuMP variables in a vertical vector pointwise
JuMP_variables = vcat(
[model[:x][i] for i in eachindex(model[:x])],
y,
z,
[model[:M][i_j] for i_j in eachindex(model[:M])]
# 💀: the line above causes the problem, wrapping it into vec(⋅) seems to fix the issue
)
# Load the heuristic solution values in a vertical vector pointwise
heuristic_values = vcat(
[x_heuristic[i] for i in eachindex(model[:x])],
y_heuristic,
z_heuristic,
[M_heuristic[i_j] for i_j in eachindex(model[:M])]
# 💀: the line above causes the problem, wrapping it into vec(⋅) seems to fix the issue
)
# Submit the heuristic solution for potentially improving the current solution
status = MOI.submit(
model, MOI.HeuristicSolution(cb_data), JuMP_variables, heuristic_values
)
println("[🙀 ] Status of the submitted heuristic solution is: ", status) # The status shows if the submitted heuristic solution is accepted or not
end
end
# IMPORTANT: This enables the heuristic
MOI.set(model, MOI.HeuristicCallback(), my_heuristic_callback_function)
# time to optimize
# --------------------
optimize!(model)
# store the solution
# ----------------------
x_opt = value.(x)
y_opt = value(y)
z_opt = value(z)
M_opt = value.(M)
p_star = objective_value(model)
Running the code above gives the error: DimensionMismatch("tried to assign 2-element array to 2×3 destination")
. The error goes away if I put the problematic lines
[model[:M][i_j] for i_j in eachindex(model[:M])]
and
[M_heuristic[i_j] for i_j in eachindex(model[:M])]
in vec(.)
function . That being said, I am not sure if this vec(.)
operation is the right way to store the heuristic values in general, as the JuMP
documentation provides somewhat simple examples, so any tips regarding the right practice will be appreciated.