Gurobi solution quality attributes prints "nothing"

Hi all!

I am trying to solve a nonconvex feasibility problem with 1 quadratic constraint in Gurobi and when the model is infeasible, it doesn’t say it is infeasible and instead, it says the solution is optimal but with the following warning:

Optimal solution found (tolerance 1.00e-09)
Warning: max constraint violation (6.6034e-07) exceeds tolerance

The problem I’m trying to solve is a part of a big algorithm and the algorithm terminates when the problem becomes infeasible. I would like to force Gurobi to return status as infeasible when the model is, infeasible. But not sure if that is doable right now (I reached out to Gurobi support but couldn’t receive any help there).

Now I want to modify my code in such a way that when Gurobi gives a similar warning/there is a violation, I want to terminate the algorithm. So my question is, is there a way in Julia to condition on this warning of Gurobi? I checked Gurobi Documentation and tried to print the maximum violation by the below command, but it prints nothing:

violation=MOI.get(model, Gurobi.ModelAttribute("MaxVio"))
print(violation)

Am I not using the command correctly? I tried all solution quality attributes of Gurobi regarding violations and all prints nothing. A bit more detailed code and the full output I get can also be found below. I would truly appreciate any help I can get on this issue. Thank you so much!

A bit more detailed code:

cm = Model(Gurobi.Optimizer)
set_optimizer_attribute(cm, "MIPGap", 1e-9)
set_optimizer_attribute(cm, "MIPFocus", 1)
set_optimizer_attribute(cm, "MIPGapAbs", 1e-8)
set_optimizer_attribute(cm, "IntFeasTol", 1e-9)
set_optimizer_attribute(cm, "Nonconvex", 2)
set_optimizer_attribute(cm, "OptimalityTol", 1e-8)
set_optimizer_attribute(cm, "FeasibilityTol", 1e-8)
set_optimizer_attribute(cm, "Cuts", 3)
set_optimizer_attribute(cm, "RLTCuts", 2)
set_optimizer_attribute(cm, "TimeLimit", timelimit)
@objective(cm, Max, 0)
#skipping the @variable and @constraint lines for simplicity
optimize!(cm)
statuscm=termination_status(cm)
print("The solution status= ")
println(statuscm)
violationcm=MOI.get(cm, Gurobi.ModelAttribute("MaxVio"))
print("The max violation is= ")
println(violationcm)

The output:

Set parameter MIPGap to value 1e-09
Set parameter MIPFocus to value 1
Set parameter MIPGapAbs to value 1e-08
Set parameter IntFeasTol to value 1e-09
Set parameter NonConvex to value 2
Set parameter OptimalityTol to value 1e-08
Set parameter FeasibilityTol to value 1e-08
Set parameter Cuts to value 3
Set parameter RLTCuts to value 2
Set parameter TimeLimit to value 60
Set parameter FeasibilityTol to value 1e-08
Set parameter Cuts to value 3
Set parameter MIPGap to value 1e-09
Set parameter MIPFocus to value 1
Set parameter RLTCuts to value 2
Set parameter OptimalityTol to value 1e-08
Set parameter IntFeasTol to value 1e-09
Set parameter NonConvex to value 2
Set parameter TimeLimit to value 60
Set parameter MIPGapAbs to value 1e-08
Gurobi Optimizer version 10.0.0 build v10.0.0rc2 (win64)

CPU model: AMD Ryzen 9 5900HX with Radeon Graphics, instruction set [SSE2|AVX|AVX2]
Thread count: 8 physical cores, 16 logical processors, using up to 16 threads

Optimize a model with 783 rows, 3307 columns and 10576 nonzeros
Model fingerprint: 0x51e3dc3f
Model has 1 quadratic constraint
Coefficient statistics:
  Matrix range     [3e-02, 5e+03]
  QMatrix range    [1e+00, 1e+00]
  QLMatrix range   [2e+02, 2e+03]
  Objective range  [0e+00, 0e+00]
  Bounds range     [0e+00, 0e+00]
  RHS range        [1e+00, 2e+01]
  QRHS range       [1e-05, 1e-05]
Presolve removed 301 rows and 17 columns

Continuous model is non-convex -- solving as a MIP

Presolve removed 399 rows and 1542 columns
Presolve time: 0.01s
Presolved: 391 rows, 1768 columns, 5598 nonzeros
Presolved model has 3 bilinear constraint(s)
Variable types: 1768 continuous, 0 integer (0 binary)

Root relaxation: objective -0.000000e+00, 513 iterations, 0.01 seconds (0.01 work units)

    Nodes    |    Current Node    |     Objective Bounds      |     Work
 Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time

     0     0   -0.00000    0    3          -   -0.00000      -     -    0s
     0     0   -0.00000    0    3          -   -0.00000      -     -    0s
     0     0   -0.00000    0    3          -   -0.00000      -     -    0s
     0     0   -0.00000    0    3          -   -0.00000      -     -    0s
     0     0   -0.00000    0    3          -   -0.00000      -     -    0s
     0     0   -0.00000    0    3          -   -0.00000      -     -    0s
     0     0   -0.00000    0    3          -   -0.00000      -     -    0s
     0     2   -0.00000    0    3          -   -0.00000      -     -    0s
     7    16   -0.00000    3    3          -   -0.00000      -   5.3   20s

Explored 4806 nodes (21136 simplex iterations) in 21.17 seconds (1.37 work units)
Thread count was 16 (of 16 available processors)

Solution count 1: -0
No other solutions better than -0

Optimal solution found (tolerance 1.00e-09)
Warning: max constraint violation (6.6034e-07) exceeds tolerance
Best objective -0.000000000000e+00, best bound -0.000000000000e+00, gap 0.0000%

User-callback calls 10228, time in user-callback 0.00 sec
The solution status= OPTIMAL
The max violation is= nothing

I think you need:

julia> MOI.get(unsafe_backend(cm), Gurobi.ModelAttribute("MaxVio"))
0.0

This is the same bug as Attributes should define is_set_by_optimize · Issue #425 · jump-dev/Gurobi.jl · GitHub.

1 Like

Yes, that worked! Thank you so much odow!

1 Like