jump-dev / Cbc.jl

A Julia interface to the Coin-OR Branch and Cut solver (CBC)
https://projects.coin-or.org/Cbc
Other
81 stars 35 forks source link

Wrong result with small values in objective #141

Closed DrChainsaw closed 4 years ago

DrChainsaw commented 4 years ago

Sorry if this is a documented/obvious/inevitable restriction.


julia> mm = JuMP.Model(JuMP.optimizer_with_attributes(Cbc.Optimizer));

julia> vv = @variable(mm, x[1:10], binary=true);

julia> oo = @objective(mm, Max, sum(vv .* eps(Float64)));

julia> optimize!(mm)
Welcome to the CBC MILP Solver
Version: 2.10.3
Build Date: Jan  1 1970

command line - Cbc_C_Interface -solve -quit (default strategy 1)
Continuous objective value is 2.22045e-15 - 0.00 seconds
Cgl0004I processed model has 0 rows, 0 columns (0 integer (0 of which binary)) and 0 elements
Cbc3007W No integer variables - nothing to do
Cuts at root node changed objective from 0 to -1.79769e+308
Probing was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
Gomory was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
Knapsack was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
Clique was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
MixedIntegerRounding2 was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
FlowCover was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
TwoMirCuts was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
ZeroHalf was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)

Result - Optimal solution found

Objective value:                0.00000000
Enumerated nodes:               0
Total iterations:               0
Time (CPU seconds):             0.05
Time (Wallclock seconds):       0.05

Total time (CPU seconds):       0.08   (Wallclock seconds):       0.08

julia> value.(vv)
10-element Array{Float64,1}:
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0

The objective value printout makes it seem like CBC itself does not produce the right result, but on the line after the command line echo it seems like it is computing the correct output.

Using eps(Float32) works, but eps(Float32)/2 fails as well.

Fwiw I got correct results with GLPK, so the issue does not seem to stem from JuMP/MOI.

odow commented 4 years ago

This is expected behavior.

Solvers use floating point arithmetic with tolerances that are typically 1e-6. Most solvers have a cut off where the consider coefficients smaller than some number to be zero. See https://www.gurobi.com/documentation/9.0/refman/num_grb_tolerances_and_the.html

You should resale your problem to coefficients between 1e-3 and 1e8 (or even smaller, if possible!)

DrChainsaw commented 4 years ago

Thanks for the explanation and link. I figured it was something like this.