I read them. Although it is ideal to have the recommended setting, in real cases numerical problematic cuts are generated via algorithms, e.g. my case.
And to update, I didn’t quite understand how Gurobi judges (the last line below)
import JuMP, Gurobi
function optimise(model)
JuMP.optimize!(model)
JuMP.assert_is_solved_and_feasible(model; allow_local = false, dual = true)
end
function test_can_cut_off(b)
model = JuMP.Model(Gurobi.Optimizer)
JuMP.set_silent(model)
JuMP.@variable(model, y)
JuMP.@objective(model, Min, 2 * y)
JuMP.@constraint(model, fixed, -9.5367431640625e-6 * y <= 2.2737367544323206e-11)
optimise(model);
yt = JuMP.value(y)
JuMP.@constraint(model, cut, c * y <= b)
optimise(model);
println("y was $yt, y is $(JuMP.value(y)). Vio = $(c * yt - b)")
end
c = -4.76837158203125e-6
base = -1.95e-9
d = 1e-11
b = base + d/5 # can cut off
test_can_cut_off(b) # y was -2.384185791015625e-6, y is 0.0004085252096. Vio = 1.9593686837721615e-9
b = base + d # cannot cut off
test_can_cut_off(b) # y was -2.384185791015625e-6, y is -2.384185791015625e-6. Vio = 1.9513686837721615e-9
# Remark: if Gurobi adopts a Vio parameter, it should be some number between 1.951e-9 and 1.959e-9, which is not very rational