Gurobi reports OPTIMAL on a QP having a huge MaxVio

WalterMadelim
Wed, 04 Jun 2025 14:47:28 +0000
Optimization (Mathematical)

julia> JuMP.unset_silent(outer)
Set parameter OutputFlag to value 1

julia> JuMP.optimize!(outer)
Gurobi Optimizer version 12.0.2 build v12.0.2rc0 (win64 - Windows 11.0 (26100.2))

CPU model: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz, instruction set [SSE2|AVX|AVX2|AVX512]
Thread count: 4 physical cores, 8 logical processors, using up to 8 threads

Optimize a model with 39 rows, 41 columns and 127 nonzeros
Model fingerprint: 0x6abf7598
Model has 38 quadratic objective terms
Coefficient statistics:
  Matrix range     [1e+00, 3e+02]
  Objective range  [9e-18, 5e+00]
  QObjective range [2e+00, 2e+00]
  Bounds range     [1e+03, 1e+03]
  RHS range        [4e+02, 2e+03]
Presolve removed 11 rows and 2 columns
Presolve time: 0.00s
Presolved: 28 rows, 39 columns, 80 nonzeros
Presolved model has 38 quadratic objective terms
Ordering time: 0.00s

Barrier statistics:
 Free vars  : 39
 AA' NZ     : 6.900e+01
 Factor NZ  : 1.060e+02
 Factor Ops : 8.340e+02 (less than 1 second per iteration)
 Threads    : 1

                  Objective                Residual
Iter       Primal          Dual         Primal    Dual     Compl     Time
   0   1.29618707e+01  1.29610499e+01  4.29e+02 1.02e+01  1.08e+06     0s
   1   7.79452936e+03 -9.29391938e+03  4.59e+01 4.59e-01  8.38e+04     0s
   2   2.34735483e+03 -3.67336088e+03  3.99e+00 4.00e-02  1.54e+04     0s
   3   9.28074635e+01 -8.89553051e+02  5.28e-01 5.42e-03  3.32e+03     0s
   4   2.67970847e+00 -2.69217523e+02  6.93e-02 1.81e-04  4.56e+02     0s
   5   4.93346415e+00 -2.33632458e+02  6.85e-02 1.78e-04  4.42e+02     0s
   6   2.61337406e+00 -2.70695461e+02  3.15e-01 1.50e-04  4.63e+02     0s
   7   1.09725171e+01 -1.34247786e+02  5.05e-01 1.37e-04  3.67e+02     0s
   8   6.15979734e+00 -7.90459574e+01  2.02e-01 6.79e-05  1.87e+02     0s
   9   2.03422156e-02 -8.54163247e+01  1.06e-01 4.22e-05  1.57e+02     0s
  10   6.28528487e-01 -3.31827999e+01  2.99e-02 4.33e-11  3.35e+01     0s
  11   1.33921978e-03 -2.70800877e+01  4.09e-13 2.12e-12  1.23e+00     0s
  12   2.55952604e-04 -3.06308511e+01  1.99e-13 2.79e-12  1.10e-02     0s
  13   3.33498799e-04 -3.42217263e+01  3.09e-13 2.70e-12  1.19e-04     0s
  14   5.57483325e-04 -3.51843270e+01  9.52e-14 1.82e-12  4.34e-07     0s
  15   2.39292335e-04 -3.74834526e+01  2.37e-13 1.82e-12  2.28e-09     0s
  16   2.43578332e-04 -3.89336401e+01  1.87e-13 2.41e-12  1.43e-10     0s
  17   2.11498031e-03 -5.43399078e+01  4.19e-02 3.42e-12  7.46e-11     0s
  18   2.96317192e-04 -5.53941734e+01  1.40e-13 5.61e-12  2.39e-12     0s
  19   4.12094691e-04 -5.67513066e+01  5.10e-14 4.84e-12  3.94e-13     0s
  20   6.75682559e-04 -5.83702637e+01  1.42e-13 1.61e-12  4.12e-16     0s
  21   8.90546712e-04 -5.95038795e+01  2.26e-13 3.58e-12  1.14e-16     0s
  22   9.87057970e-04 -6.26382723e+01  1.59e-13 3.55e-12  2.54e-19     0s

Barrier solved model in 22 iterations and 0.01 seconds (0.00 work units)
Optimal objective 9.87057970e-04


User-callback calls 113, time in user-callback 0.00 sec

julia> JuMP.solution_summary(outer)
solution_summary(; result = 1, verbose = false)
├ solver_name          : Gurobi
├ Termination
│ ├ termination_status : OPTIMAL
│ ├ result_count       : 1
│ ├ raw_status         : Model was solved to optimality (subject to tolerances), and an optimal solution is available.
│ └ objective_bound    : -2.70801e+01
├ Solution (result = 1)
│ ├ primal_status        : FEASIBLE_POINT
│ ├ dual_status          : FEASIBLE_POINT
│ ├ objective_value      : 9.87058e-04
│ └ dual_objective_value : -4.97810e+01
└ Work counters
  ├ solve_time (sec)   : 7.99990e-03
  ├ simplex_iterations : 0
  ├ barrier_iterations : 22
  └ node_count         : 0

julia> vio = JuMP.MOI.get(JuMP.backend(outer), Gurobi.ModelAttribute("MaxVio"))
43.97206084166428

julia> Gurobi.GRBwrite(JuMP.unsafe_backend(outer), "outer.mps")
0

This “OPTIMAL” solution is very weird—noticing the MaxVio, and the termination gap. Is this normal? (@odow I remember that there was also a gap displayed here)

The code to reproduce this model outer is here. (A lightweight PGlib.jl data package is required.)
code (click for more details)
9 posts - 2 participants