Gurobi callback function not accessing / not loading

Hello,

I would like to access the values during each iterations, then plot the objective function (maybe more info) against iterations, I wrote a callback function as below. I found that my cb_where is never equal to GRB_CB_MIP or GRB_CB_SIMPLEX, so that this "I’m here… " phrase is never printed…

Then, I want to try something solver-independent with my_callback_function2, but it’s not working as well…

Thanks ahead for help.

env = Gurobi.Env()
ot_model = direct_model(Gurobi.Optimizer(env))
# ot_model = Model(Gurobi.Optimizer)


@variable(ot_model, p[1:I, 1:J] >= 0)
@variable(ot_model, z[1:I])
@constraint(ot_model, p * ones(J) .== ones(I))
@constraint(ot_model, transpose(p) * μ .== ν)
@constraint(ot_model, [i = 1:I], z[i] >= (X[i] - (p * Y)[i])^2)
@objective(ot_model, Min, sum(μ[i] * z[i] for i = 1:I))


function my_callback_function1(cb_data, cb_where::Cint)
    # GRB_CB_SIMPLEX GRB_CB_MIP
        
    if cb_where == GRB_CB_MIP || cb_where == GRB_CB_SIMPLEX ||cb_where ==  GRB_CB_MIPSOL
        
        print("I'm here... ")
        Gurobi.load_callback_variable_primal(cb_data, cb_where)
        z_val = callback_value(cb_data, z)
        print("The currenct z value is ", z_val)
    end
end

function my_callback_function2(cb_data)
    z_val = callback_value(cb_data, z)
    print("The currenct z value is ", z_val)
end


MOI.set(ot_model, Gurobi.CallbackFunction(), my_callback_function2)

optimize!(ot_model)

If you want to get the current best objective on each new MIP incumbent node, you should use the GRB_CB_MIPSOL_OBJBST code on new MIP nodes (GRB_CB_MIPSOL) as follows:

function my_callback_function(cb_data, cb_where)
    if cb_where == GRB_CB_MIPSOL
        current_best_obj = Ref{Cdouble}()
        GRBcbget(cb_data, cb_where, GRB_CB_MIPSOL_OBJBST, current_best_obj)
        current_best_obj_val = current_bestobj[]
        println("Current best objective: $current_best_obj_val")
    end
end

As for solver independent callbacks, it depends on which solvers you will be working with, personally I find it better to write solver specific callbacks.

If you want, you can provide a MWE and I can try to run your model to see what’s happening

Actually I am just looking at your model and you have a quadratic term there so that may have something to do, not sure, will look into it, but I definitely can run the model if you want to.

Hi @cskx, welcome to the forum.

The Gurobi cb_where codes are Callback Codes - Gurobi Optimization

You could see where the callback is being called from with

function my_callback_function1(cb_data, cb_where::Cint)
    print("Calling from $cb_where")
end

MOI.set(ot_model, Gurobi.CallbackFunction(), my_callback_function1)

The answer for your problem is probably that it isn’t a MIP, so GRB_CB_MIP and GRB_CB_MIPSOL are never called, and Gurobi doesn’t solve this with the simplex method, so GRB_CB_SIMPLEX is never called.

For the solver independent callback, you need to follow Solver-independent Callbacks · JuMP. This likely won’t work with Gurobi because these callbacks are intended only for MIPs, and your problem does not have integer variables.

2 Likes

Thank you so much @odow !! Finally I found out that my callback is being called at Barrier, and then I adapted your response from another post…

GRBcbget(cb_data, cb_where, GRB_CB_BARRIER_PRIMOBJ, primal_val)

Thanks once a again, I appreciate it !! : )

1 Like

Hi, thank you for helping, actually it was running on GRB_CB_BARRIER instead of GRB_CB_MIPSOL. I just solved the problem with odow’s response. Thanks

2 Likes