User cuts and Lazy Constraints JuMP Gurobi

I am trying to insert user cuts and lazy constraints in a mixed-integer linear programming model. I am putting the functions in separate files from the main model. An illustrative example:

function valid_inequality(cb_data)
con = @constraint([i in 1:m,j in 1:n, k in 1:n], sum(X[i,j,k,l] for l in 1:s)<=1)
MOI.submit(model, MOI.UserCutCallback(), con)
end

in the main file:
MOI.set(model, MOI.UserCutCallback(), valid_inequality)

And Julia is returning:
UndefVarError: i not defined

The examples of user cuts and lazy constraints in the JuMP documentation does not present decision variables with several indices.

Thanks in advance,
Bruno

Please, enclosure your code in triple backticks to make it easier to read:

```
code
```

becomes

code

Second, I do not think you should call @constraint without passing a model as first argument. If you read the documentation for @constraint you will see that to build a constraint without immediately associating it to a model you should use @build_constraint , that is inside a page called Callbacks API.

Dear Henrique. Thank you for your feedback. Regarding the source code, my mistake. I am sending the code again:

function valid_inequality(cb_data)
con = @I constraint([i in 1:m,j in 1:n, k in 1:n], sum(X[i,j,k,l] for l in 1:s)<=1)
MOI.submit(model, MOI.UserCutCallback(), con)
end

in the main file:

MOI.set(model, MOI.UserCutCallback(), valid_inequality)

And Julia is returning:

UndefVarError: i not defined

I replace @constraint with @build_constraint, following your suggestion.

I am trying to solve the problem.

Where can I find an example about user-cuts and lazy constraints with decision variables with multiple dimensions? In the documentation, the decision variable presents a single dimension:
https://jump.dev/JuMP.jl/dev/callbacks/#callbacks_manual

Thanks in advance,
Bruno

I think the @build_constraint macro (that is the right one to call here) does not support this syntax, it only builds one constraint per call. Probably they forgot or never considered in the first place, does not seem intentional.

You would need to do something like this:

cuts_to_add = Any[] # maybe tighten the typing someday
for i in 1:m,j in 1:n, k in 1:n
    cut = @build_constraint(sum(X[i,j,k,l] for l in 1:s)<=1)
    push!(cuts_to_add, cut)
end
MOI.submit.((model,), (MOI.UserCutCallback(),), cuts_to_add)

Maybe it is not the best performant code but it should work.

1 Like

Dear Henrique,

Thank you very much for your attention. I have inserted this code, and it works fine. Thanks.

    function cuts_to_add(cb_data)
        for i in 1:m, j in 1:n, k in 1:n
            cut = @build_constraint(sum(X[i,j,k,l] for l in 1:s)<=1)
            MOI.submit(model, MOI.UserCut(cb_data), cut)
        end
    end

    MOI.set(model, MOI.UserCutCallback(), cuts_to_add)
1 Like