How to gain access variables as soons as they are assigned a value?

I was wondering whether in JuMP is possible to be aware of the value of variables while the model is still running?? I mean, suppose we have a set of binary variables x(i,j) i,j in [1,2,3,...,n]. Is there any possiblity to know which variable get the value of one, immediately. for example, and as soons as model assignsx(1,2) =1 is it possible to know? Or we have to wait untill the model is entirely done.

What do you mean by the value some variable assume while the model is running?

  1. When the model find an incumbent solution? (Note the values here may different from the final solution.)
  2. While the code is branching? The “bounding constraints” that force things like x(1, 2) == 1 may be delimiting a search space without feasible solutions.
  3. When the pruned branches plus the incumbent may be used as proof that the solution to be returned will have x(1, 2) == 1?

If you post in multiple places, please provide cross-links so we don’t answer the same question twice:

Copy-pasting my answer:

JuMP supports three solver-independent callbacks:

  • Lazy constraints
  • User cuts
  • Heuristic callbacks

Docs:

You can also write a solver-dependent callback for solvers like Gurobi. Check the README of each solver.

Here’s the example:

using JuMP, Gurobi, Test

model = direct_model(Gurobi.Optimizer())
@variable(model, 0 <= x <= 2.5, Int)
@variable(model, 0 <= y <= 2.5, Int)
@objective(model, Max, y)
cb_calls = Cint[]
function my_callback_function(cb_data, cb_where::Cint)
    # You can reference variables outside the function as normal
    push!(cb_calls, cb_where)
    # You can select where the callback is run
    if cb_where != GRB_CB_MIPSOL && cb_where != GRB_CB_MIPNODE
        return
    end
    # You can query a callback attribute using GRBcbget
    if cb_where == GRB_CB_MIPNODE
        resultP = Ref{Cint}()
        GRBcbget(cb_data, cb_where, GRB_CB_MIPNODE_STATUS, resultP)
        if resultP[] != GRB_OPTIMAL
            return  # Solution is something other than optimal.
        end
    end
    # Before querying `callback_value`, you must call:
    Gurobi.load_callback_variable_primal(cb_data, cb_where)
    x_val = callback_value(cb_data, x)
    y_val = callback_value(cb_data, y)
    # You can submit solver-independent MathOptInterface attributes such as
    # lazy constraints, user-cuts, and heuristic solutions.
    if y_val - x_val > 1 + 1e-6
        con = @build_constraint(y - x <= 1)
        MOI.submit(model, MOI.LazyConstraint(cb_data), con)
    elseif y_val + x_val > 3 + 1e-6
        con = @build_constraint(y + x <= 3)
        MOI.submit(model, MOI.LazyConstraint(cb_data), con)
    end
    if rand() < 0.1
        # You can terminate the callback as follows:
        GRBterminate(backend(model))
    end
    return
end
# You _must_ set this parameter if using lazy constraints.
MOI.set(model, MOI.RawOptimizerAttribute("LazyConstraints"), 1)
MOI.set(model, Gurobi.CallbackFunction(), my_callback_function)
optimize!(model)
@test termination_status(model) == MOI.OPTIMAL
@test primal_status(model) == MOI.FEASIBLE_POINT
@test value(x) == 1
@test value(y) == 2
3 Likes

Hi @odow thanks a lot. I’m sorry. I asked one of my firends and it seems he asked there!! Whithout telling me.

1 Like

No problem :smile: I saw it this time. Just remember for next time.

1 Like

Sure. I tell him too. Thanks a lot again!

1 Like