Gurobi12 reports OPTIMAL to an NLP which is actually UNbounded

Continuing the discussion from Gurobi12 Reports unbounded to a nonconvex QP which is actually bounded:

import JuMP, Gurobi
NLP = JuMP.Model(Gurobi.Optimizer);
JuMP.@variable(NLP, x);
JuMP.@objective(NLP, Min, (x + 1) * x * (x - 1));
JuMP.optimize!(NLP);
Gurobi Optimizer version 12.0.1 build v12.0.1rc0 (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 0 rows, 3 columns and 0 nonzeros
Model fingerprint: 0x60c267e2
Model has 1 general nonlinear constraint (2 nonlinear terms)
Variable types: 3 continuous, 0 integer (0 binary)
Coefficient statistics:
  Matrix range     [0e+00, 0e+00]
  Objective range  [1e+00, 1e+00]
  Bounds range     [0e+00, 0e+00]
  RHS range        [0e+00, 0e+00]
Found heuristic solution: objective 0.0000000
Presolve model has 1 nlconstr
Added 4 variables to disaggregate expressions.
Presolve time: 0.00s
Presolved: 10 rows, 8 columns, 22 nonzeros
Presolved model has 2 bilinear constraint(s)

Solving non-convex MIQCP

Variable types: 8 continuous, 0 integer (0 binary)
Found heuristic solution: objective -0.3849002

Root relaxation: unbounded, 1 iterations, 0.00 seconds (0.00 work units)

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

     0     0  postponed    0        -0.38490          -      -     -    0s
omit lines....
*  934    43             124    -210.0000000          -      -   0.3    0s
H 8396  1056                    -627.4375000 -5.369e+14      -   0.2    0s
omit lines....
 4747770    24 -5.369e+14 39299    1 -2.621e+11 -5.369e+14      -   0.0  120s
 4762410    24 -5.369e+14 39909    1 -2.621e+11 -5.369e+14      -   0.0  125s
H4763874    24                    -1.00000e+18 -1.000e+18  0.00%   0.0  125s

Explored 4765338 nodes (186361 simplex iterations) in 125.93 seconds (11.38 work units)
Thread count was 8 (of 8 available processors)

Solution count 10: -1e+18 -3.74409e+09 -3.44774e+09 ... -2.60131e+09
No other solutions better than -1e+18

Optimal solution found (tolerance 1.00e-04)
Best objective -9.999999999990e+17, best bound -9.999999999990e+17, gap 0.0000%

User-callback calls 9533859, time in user-callback 2.53 sec

The primal objVal is fine, as it monotonically decreases.
But it’s weird to see the ObjBound firstly goes up and later goes down (the last 2 lines of MIP Logging).
Furthermore,

julia> JuMP.termination_status(NLP)
OPTIMAL::TerminationStatusCode = 1

julia> JuMP.primal_status(NLP)
FEASIBLE_POINT::ResultStatusCode = 1

julia> JuMP.objective_value(NLP)
-9.99999999999e17

julia> valueP = Ref{Cdouble}()
Base.RefValue{Float64}(1.202678831762e-311)

julia> err_code = Gurobi.GRBgetdblattr(JuMP.unsafe_backend(NLP), "MaxVio", valueP)
0

julia> valueP[]
0.0

It doesn’t terminates with GRB_INFINITY.

This is likely a related bug to the previous one you found. I’ll add it to my support ticket.

You should understand the the MINLP solver in Gurobi is new. It is expected that there are a number of bugs, especially with these edge-case models.

1 Like

Thank you very much.

Actually here is a nonconvex QCP reformulation of the above NLP, which can be run much faster. This time the upside is: a warning can be seen in Gurobi’s Logging.

The errors are

  1. the best bound shouldn’t first go up and then go down.
  2. the termination status shouldn’t be OPTIMAL

Please take a look (Since this is nonconvex QCP, I think Gurobi 9 could do it)

julia> import JuMP, Gurobi

julia> ncQCP = JuMP.Model(Gurobi.Optimizer) # non-convex QCP
Set parameter Username
Set parameter LicenseID to value 2602363
Academic license - for non-commercial use only - expires 2025-12-20
A JuMP Model
├ solver: Gurobi
├ objective_sense: FEASIBILITY_SENSE
├ num_variables: 0
├ num_constraints: 0
└ Names registered in the model: none

julia> JuMP.@variable(ncQCP, x)
x

julia> JuMP.@variable(ncQCP, xx)
xx

julia> JuMP.@constraint(ncQCP, xx >= x * x)
-x² + xx >= 0

julia> JuMP.@constraint(ncQCP, xx <= x * x)
-x² + xx <= 0

julia> JuMP.@objective(ncQCP, Min, x * (xx - 1))
x*xx - x

julia> JuMP.optimize!(ncQCP)
Gurobi Optimizer version 12.0.1 build v12.0.1rc0 (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 0 rows, 2 columns and 0 nonzeros
Model fingerprint: 0xb0bb3f9e
Model has 1 quadratic objective term
Model has 2 quadratic constraints
Coefficient statistics:
  Matrix range     [0e+00, 0e+00]
  QMatrix range    [1e+00, 1e+00]
  QLMatrix range   [1e+00, 1e+00]
  Objective range  [1e+00, 1e+00]
  QObjective range [2e+00, 2e+00]
  Bounds range     [0e+00, 0e+00]
  RHS range        [0e+00, 0e+00]

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

Found heuristic solution: objective 0.0000000
Presolve time: 0.00s
Presolved: 3 rows, 4 columns, 6 nonzeros
Presolved model has 1 quadratic constraint(s)
Presolved model has 2 bilinear constraint(s)
Warning: Model contains variables with very large bounds participating
         in product terms.
         Presolve was not able to compute smaller bounds for these variables.
         Consider bounding these variables or reformulating the model.

Variable types: 4 continuous, 0 integer (0 binary)

Root relaxation: unbounded, 1 iterations, 0.00 seconds (0.00 work units)

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

     0     0  unbounded    0         0.00000          -      -     -    0s
     0     0  postponed    0         0.00000          -      -     -    0s
     0     0  postponed    0         0.00000          -      -     -    0s
     0     0  postponed    0         0.00000          -      -     -    0s
     0     2  postponed    0         0.00000          -      -     -    0s
*    1     2               1    -9.99999e+08          -      -   4.0    0s
*    4     2               2    -2.82843e+09          -      -   2.3    0s
*    7     4               4    -8.00000e+09          -      -   2.0    0s
*   21     4               5    -2.26274e+10          -      -   1.8    0s
*   23     4               8    -6.40000e+10          -      -   1.8    0s
*   45     4              11    -1.81019e+11          -      -   1.7    0s
*   99     6              28    -1.81029e+11          -      -   1.4    0s
*  119    13              29    -1.81039e+11          -      -   1.3    0s
*  140    19              35    -1.81096e+11          -      -   1.2    0s
H  158    24                    -1.81163e+11          -      -   1.1    0s
H  191    42                    -1.81288e+11          -      -   0.9    0s
*  270    42              69    -1.81423e+11          -      -   0.7    0s
*  368    60              71    -1.81442e+11          -      -   0.5    0s
*  369    60              72    -1.81452e+11          -      -   0.5    0s
*  372    60              73    -1.81461e+11          -      -   0.5    0s
*  430    66              74    -1.81471e+11          -      -   0.5    0s
*  433    66              75    -1.81481e+11          -      -   0.5    0s
*  434    66              76    -1.81490e+11          -      -   0.5    0s
*  437    66              77    -1.81500e+11          -      -   0.5    0s
*  438    66              78    -1.81509e+11          -      -   0.5    0s
*  441    66              79    -1.81519e+11          -      -   0.5    0s
*  442    66              80    -1.81529e+11          -      -   0.5    0s
*  445    66              81    -1.81538e+11          -      -   0.5    0s
*  446    66              82    -1.81548e+11          -      -   0.5    0s
H  501    84                    -1.81596e+11          -      -   0.4    0s
*  527    84              88    -1.81606e+11          -      -   0.4    0s
*  530    84              89    -1.81615e+11          -      -   0.4    0s
*  531    84              90    -1.81625e+11          -      -   0.4    0s
*  534    84              91    -1.81634e+11          -      -   0.4    0s
*  535    84              92    -1.81644e+11          -      -   0.4    0s
*  538    84              93    -1.81654e+11          -      -   0.4    0s
*  539    84              94    -1.81663e+11          -      -   0.4    0s
H  602    94                    -1.81673e+11          -      -   0.4    0s
*  627    94              96    -1.81683e+11          -      -   0.4    0s
*  630    94              97    -1.81692e+11          -      -   0.4    0s
*  631    94              98    -1.81702e+11          -      -   0.4    0s
*  634    94              99    -1.81711e+11          -      -   0.4    0s
*  635    94             100    -1.81721e+11          -      -   0.4    0s
*  638    94             101    -1.81731e+11          -      -   0.4    0s
*  639    94             102    -1.81740e+11          -      -   0.4    0s
*  642    94             103    -1.81750e+11          -      -   0.4    0s
*  643    94             104    -1.81760e+11          -      -   0.4    0s
H  645    94                    -1.81769e+11          -      -   0.4    0s
*  647    94             106    -1.81779e+11          -      -   0.4    0s
*  650    94             107    -1.81788e+11          -      -   0.4    0s
*  651    94             108    -1.81798e+11          -      -   0.4    0s
*  743    66             109    -1.81808e+11          -      -   0.3    0s
*  744    66             110    -1.81817e+11          -      -   0.3    0s
*  966   116             151    -1.82212e+11          -      -   0.3    0s
* 1563   145              18    -5.12000e+11 -5.369e+14      -   0.2    0s
* 1566   136              19    -1.44815e+12 -5.369e+14      -   0.2    0s
* 1567   129              20    -4.09600e+12 -5.369e+14      -   0.2    0s
* 1569   121              21    -1.15852e+13 -5.369e+14  4534%   0.2    0s
* 1571   115              22    -3.27680e+13 -5.369e+14  1538%   0.2    0s
* 1574   108              24    -2.62144e+14 -5.369e+14   105%   0.2    0s
* 1576   101              25    -7.41455e+14 -7.415e+14  0.00%   0.2    0s

Explored 1579 nodes (341 simplex iterations) in 0.06 seconds (0.00 work units)
Thread count was 8 (of 8 available processors)

Solution count 10: -7.41455e+14 -2.62144e+14 -3.2768e+13 ... -1.81808e+11
No other solutions better than -7.41455e+14

Optimal solution found (tolerance 1.00e-04)
Best objective -7.414552000990e+14, best bound -7.414552000990e+14, gap 0.0000%

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

julia> JuMP.solution_summary(ncQCP; verbose = true)
* Solver : Gurobi

* Status
  Result count       : 10
  Termination status : OPTIMAL
  Message from the solver:
  "Model was solved to optimality (subject to tolerances), and an optimal solution is available."

* Candidate solution (result #1)
  Primal status      : FEASIBLE_POINT
  Dual status        : NO_SOLUTION
  Objective value    : -7.41455e+14
  Objective bound    : -7.41455e+14
  Relative gap       : 0.00000e+00
  Primal solution :
    x : -9.05097e+04
    xx : 8.19200e+09

* Work counters
  Solve time (sec)   : 5.99999e-02
  Simplex iterations : 341
  Barrier iterations : 0
  Node count         : 1579

I’ve submitted a support request with both models.

1 Like

I’m very sorry but I find yet another bug of Gurobi.
In the following test case I am essentially Minimize x, where x is free.
But Gurobi reports OPTIMAL

julia> import JuMP, Gurobi

julia> begin
           model = JuMP.Model(Gurobi.Optimizer)
               JuMP.@variable(model, x)
           JuMP.@variable(model, trivial_decision)
           JuMP.@constraint(model, trivial_decision >= x * x)
           JuMP.@constraint(model, trivial_decision <= x * x)
           JuMP.@objective(model, Min, x)
       end
julia> JuMP.optimize!(model)
Gurobi Optimizer version 12.0.1 build v12.0.1rc0 (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 0 rows, 2 columns and 0 nonzeros
Model fingerprint: 0x862a5994
Model has 2 quadratic constraints
Coefficient statistics:
  Matrix range     [0e+00, 0e+00]
  QMatrix range    [1e+00, 1e+00]
  QLMatrix range   [1e+00, 1e+00]
  Objective range  [1e+00, 1e+00]
  Bounds range     [0e+00, 0e+00]
  RHS range        [0e+00, 0e+00]

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

Found heuristic solution: objective 0.0000000
Presolve time: 0.00s
Presolved: 1 rows, 3 columns, 2 nonzeros
Presolved model has 1 quadratic constraint(s)
Presolved model has 1 bilinear constraint(s)
Warning: Model contains variables with very large bounds participating
         in product terms.
         Presolve was not able to compute smaller bounds for these variables.
         Consider bounding these variables or reformulating the model.

Variable types: 3 continuous, 0 integer (0 binary)

Root relaxation: unbounded, 0 iterations, 0.00 seconds (0.00 work units)

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

     0     0  unbounded    0         0.00000          -      -     -    0s
     0     0  unbounded    0         0.00000          -      -     -    0s
     0     0  unbounded    0         0.00000          -      -     -    0s
     0     0  unbounded    0         0.00000          -      -     -    0s
     0     0  unbounded    0         0.00000          -      -     -    0s
     0     0  postponed    0         0.00000          -      -     -    0s
     0     0  postponed    0         0.00000          -      -     -    0s
     0     2  postponed    0         0.00000          -      -     -    0s
* 1298   995              14    -1000000.000          -      -   0.0    0s
* 1340   933              34    -1024000.000          -      -   0.0    0s
* 1347   889              38    -1447680.982          -      -   0.0    0s
* 1348   844              38    -1447695.168          -      -   0.0    0s
* 1353   800              40    -1448099.336          -      -   0.0    0s
* 1366   755              36    -2048000.000          -      -   0.0    0s
* 1369   716              38    -2895659.103          -      -   0.0    0s
* 1380   669              38    -4096000.000 -4096000.0  0.00%   0.0    0s

Explored 1383 nodes (45 simplex iterations) in 0.66 seconds (0.25 work units)
Thread count was 8 (of 8 available processors)

Solution count 9: -4.096e+06 -2.89566e+06 -2.048e+06 ... 0
No other solutions better than -4.096e+06

Optimal solution found (tolerance 1.00e-04)
Best objective -4.096000000000e+06, best bound -4.096000000000e+06, gap 0.0000%

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

julia> JuMP.solution_summary(model; verbose = true)
* Solver : Gurobi

* Status
  Result count       : 9
  Termination status : OPTIMAL
  Message from the solver:
  "Model was solved to optimality (subject to tolerances), and an optimal solution is available."

* Candidate solution (result #1)
  Primal status      : FEASIBLE_POINT
  Dual status        : NO_SOLUTION
  Objective value    : -4.09600e+06
  Objective bound    : -4.09600e+06
  Relative gap       : 0.00000e+00
  Primal solution :
    trivial_decision : 1.67772e+13
    x : -4.09600e+06

* Work counters
  Solve time (sec)   : 6.59000e-01
  Simplex iterations : 45
  Barrier iterations : 146215
  Node count         : 1383

But we may learn from this case that if Gurobi prints Warning, then it may be a sign of potential misfortune. Therefore we have to also strive to eliminate solver’s Warnings to ensure normality, and the expected behavior.

1 Like

I’ll add it to the list. I assume that these are all in fact different models that hit the same bug, rather than different bugs entirely.