Gurobi's trial solution is numerically weird on a primitive CTPLN model

Although this might not necessarily be deemed a bug, it’s certainly a bit weird. Why?

julia> import JuMP, Gurobi; GRB_ENV = Gurobi.Env();
Set parameter Username
Set parameter LicenseID to value 2663413
Academic license - for non-commercial use only - expires 2026-05-11

julia> import LinearAlgebra.⋅ as ⋅

julia> import Random; Random.seed!(3);

julia> S, I, J, c, W, w, d = let # Don't care this
           S = 8
           I = 20
           dl, dh = rand(7:14), rand(57:77)
           d = rand(dl:dh, I, S)
           δ = 1.7e-6
           wl, wh = rand(1.3:δ:3.5), rand(7.7:δ:9.7)
           w = rand(wl:δ:wh, I)
           J = 185
               Wl, Wh = rand(9.7:δ:18.3), rand(45.3:δ:60.7)
           W = rand(Wl:δ:Wh, J)
           c = 0.1rand(0.99:δ:1.99, J) .* W
           S, I, J, c, W, w, d
       end;

julia> extrema(c) # This vector is numerically normal
(1.1132344320884253, 8.724885200774779)

julia> length(c)
185

julia> begin
           St1 = JuMP.Model(() -> Gurobi.Optimizer(GRB_ENV)); # the stage-1 (master) problem
           JuMP.@variable(St1, b[1:J], Bin);
           JuMP.@variable(St1, θ[1:S]);
           JuMP.@expression(St1, common, c ⋅ b);
           JuMP.@expression(St1, St1_obj_tbMin, common + sum(θ));
           JuMP.@constraint(St1, St1_obj_tbMin ≥ 0);
           JuMP.@objective(St1, Min, St1_obj_tbMin);
               JuMP.optimize!(St1); JuMP.assert_is_solved_and_feasible(St1; allow_local = false)
       end;
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 1 rows, 193 columns and 193 nonzeros
Model fingerprint: 0x38f34061
Variable types: 8 continuous, 185 integer (185 binary)
Coefficient statistics:
  Matrix range     [1e+00, 9e+00]
  Objective range  [1e+00, 9e+00]
  Bounds range     [0e+00, 0e+00]
  RHS range        [0e+00, 0e+00]
Found heuristic solution: objective 0.0000000
Found heuristic solution: objective -0.0000001
Presolve removed 1 rows and 193 columns
Presolve time: 0.02s
Presolve: All rows and columns removed

Explored 0 nodes (0 simplex iterations) in 0.02 seconds (0.00 work units)
Thread count was 1 (of 8 available processors)

Solution count 2: -1.19209e-07 0

Optimal solution found (tolerance 1.00e-04)
Best objective -1.192092895508e-07, best bound -1.192092895508e-07, gap 0.0000%

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

julia> JuMP.value.(θ) # The scale of this solution is abnormally large
8-element Vector{Float64}:
 -7.000000000000001e8
  1.0e8
  1.0e8
  1.0e8
  1.0e8
  1.0e8
  1.0e8
  1.0e8

This is not a bug.

Gurobi doesn’t make any claims about which solution it will return if multiple are available. You Don’t have bounds on θ, so any solution that sums to 0.0 is as valid as any other.

1 Like