Is it expected that a zero-one variable may have a non-integer value after an optimal solution is found?

I formulate a mathematical optimization (MIQCP) problem with MathOptInterface.jl and solve it with Gurobi.jl. Certain variables in my problem are constrained (with MOI.add_constrained_variables(optimizer, [MOI.ZeroOne() for _ ∈ 1:n])) to be Boolean. After MOI.optimize!(optimizer) is done, I check that MOI.get(optimizer, MOI.TerminationStatus()) == MOI.OPTIMAL, then retrieve the values of the variables using MOI.get(optimizer, MOI.VariablePrimal(), logical_vars).

To my surprise, the value of such a variable need not be integral, in one case it’s prevfloat(1.0, 7), very close to one, but not exactly integral.

Is this expected, or is it a bug?

I guess my workaround will be such, does it seem OK:

x = MOI.get(optimizer, MOI.VariablePrimal(), logical_variable)
ub = 1e-50
lb = true - 1e-10
((false ≤ x ≤ ub) | (lb ≤ x ≤ true)) || error("unexpected")
y = round(Bool, x)
1 Like

This is under the default integer feasibility tolerance of 1e-5, so this is expected.
From: Why does Gurobi sometimes return non-integral values for integer variables? you can tighten this up or set the IntegralityFocus parameter to 1.


I guess there’s no option like IntegralityFocus for MathOptInterface.jl in general? Would it make sense to add it to MOI?

Actually, I can’t figure out how to set the IntegralityFocus Gurobi parameter from Julia at all. How to do it?

You can set it using JuMPs set_attribute or set_optimizer_attribute or even MOI.RawOptimizerAttribute


Thanks! I ended up doing this, in addition to the above workaround:

import Gurobi as Opt
const gurobi_environment = Opt.Env()
import MathOptInterface as MOI
function make_opt()
  opt = Opt.Optimizer(gurobi_environment)
  MOI.set(opt, MOI.Silent(), true)
  MOI.set(opt, MOI.RawOptimizerAttribute("IntegralityFocus"), true)
my_program(make_opt, ...)

The MOI.Silent is there because otherwise Gurobi seems to print a line about setting the IntegralityFocus parameter each time that happens, which is each time an optimization problem gets formulated and solved.