Closed 4er4er4er closed 1 year ago
The reason was a too small eps=1e-6 for strict comparison of continuous variables in MIPConverter. For Ship[i,j] >= minload
to count as false
it was enough to be 374.999999 which was reported as 375 by Gurobi.
Changed the default comparison eps to 1e-3 and added option cvt:mip:eps for it.
The message glitch: see #158
As I understand the situation, minload is 375, and for some i and j the constraint
Ship[i,j] = 0 or minload <= Ship[i,j] <= limit[i,j]
is considered by Gurobi to be satisfied by Ship[i,j] = 374.999999. But in the constraint
count {j in DEST} (Ship[i,j] >= minload) <= maxserve
the condition Ship[i,j] >= minload
evaluates to False when Ship[i,j] = 374.999999, due to the use of a different tolerance for this comparison. Is that right? If so, I have two questions:
First, is it enough to increase the second tolerance slightly (even to 9e-5) rather than to a much larger value like 1e-3?
Second, why does the optimal value appear as 375 in AMPL rather than as 374.999999? Even when I set option display_precision 0;
to request "full" precision is displays, it appears as 375:
ampl: option display_precision 0;
ampl: display Ship;
Ship [*,*] (tr)
: CLEV GARY PITT :=
DET 625 0 525
FRA 425 0 475
FRE 425 375 375
LAF 0 400 600
LAN 500 0 0
STL 625 625 550
WIN 0 0 375
;
I guess it is being rounded somewhere, but I am curious as to where it is being rounded.
Checking Gurobi output (obtained by solving its own LP instance exported), the values are already 375. Probably, when Gurobi checks indicator constraints, it uses the same feasibility tolerance.
9e-5 is almost 1e-4. Are there any solvers with default FeasTol 1e-4 or more? If no, we could set anything as default which seems safe.
Otherwise, we could make cvt:mip:eps a Backend parameter, i.e., solver-dependent, and the Backend would be responsible for setting a custom default value.
I wasn't thinking straight when I said 9e-5. What I intended to ask was: To avoid the problem we're seeing, is it enough to slightly increase the tolerance applied to Ship[i,j] >= minload
from the previous value of 1e-6? That could be for example an increase to 2e-6.
It appears that 1e-6 is a very common feasibility tolerance; it's the default in Gurobi, CPLEX, Xpress, Knitro, and MINOS, for example. The user can change this tolerance, however, by setting a "feastol" solver option. Thus our solver interface should (ideally) adapt to the feasibility tolerance setting that the solver is actually going to use.
I am trying to understand what solution you are describing when you refer to "Checking Gurobi output (obtained by solving its own LP instance exported)." I have in mind that there might be two solutions involved:
So the first thing I am wondering is, what is the solution (1) returned by the Gurobi API call in this case -- 374.999999 or 375? Then depending on that, I might have some other questions.
Gurobi API returns 375.0.
We could have the following mechanism. When cvt:mip:eps<0 (default -1e-6 for example), the tolerance is set to feastol-(cvt:mip:eps). Otherwise it's the given value. Or, just describe the matter in option text.
Continued with escrow/#102.
I modified the book example multmip3.mod (see attached files) to a version called x-multmip3.mod that uses various logical operators and functions instead of binary variables (see Total_Cost, Ship_Range, and Max_Serve):
When solved using multmip3.mod + multmip3.dat, the optimal value is 235625. When solved using x-multmip3.mod + multmip3.dat, the optimal value is reported in the solver message as 231650, but the objective Total_Cost displays (correctly) as 233150. Also one of the Max_Serve constraints is violated (which accounts for the lower objective value):
(Note also the glitch in the solver message:
x-Gurobi 9.5.0: Set parx-Gurobi 9.5.0: optimal solution; objective 231650
.)