Re: Solver delivers wrong answer when 2 constraints are close
Domingo Alvarez Duarte <[email protected]> Thu, 4 Mar 2021 19:07:25 +0100
| Newsgroups | gmane.comp.gnu.glpk |
|---|---|
| Message-ID | <[email protected]> |
Hello João ! If the model/data that you tested could be public, do you mind share then ? Cheers ! On 4/3/21 19:00, João Flávio de Freitas Almeida wrote: > Dear all, > > Maybe it is a design flaw, or an AMPL issue but recently, I run the > same model with Glpk and Ampl-Gurobi. > The optimal solution were different. > > *GLPK: *3.328774238e+09 > *AMPL-Gurobi: *3.360308548e+09 > > # ========================================================== # > GLPSOL: GLPK LP/MIP Solver, v4.65 > Parameter(s) specified in the command line: > -m v9_3flass_glpk.mod -d v9_dados.dat -d 12_dados.dat -d > 12_distancias.txt > --cuts --tmlim 7200 --log v9_log.log > Reading model section from v9_3flass_glpk.mod... > 674 lines were read > Reading data section from v9_dados.dat... > 112 lines were read > Reading data section from 12_dados.dat... > 61 lines were read > Reading data section from 12_distancias.txt... > 491 lines were read > Checking (line 184)... > Checking (line 242)... > Checking (line 243)... > Checking (line 244)... > Generating of... > Generating R1a... > Generating R2... > Generating R3... > Generating R4... > Generating R5... > Generating R6... > Generating R7a... > Generating R7b... > Generating R7c... > Generating R8... > Generating R9... > Generating R10... > Generating R10a... > Generating R11... > Generating R11a... > Generating R11b... > Generating R12... > Generating R12b... > Generating R13... > Generating R14... > Generating R15... > Generating R16... > Generating R17... > Generating R18... > Generating R19... > Generating R20... > Generating R21... > Model has been successfully generated > GLPK Integer Optimizer, v4.65 > 5139 rows, 1248 columns, 23444 non-zeros > 608 integer variables, all of which are binary > Preprocessing... > 165 constraint coefficient(s) were reduced > 766 rows, 1019 columns, 15790 non-zeros > 509 integer variables, all of which are binary > Scaling... > A: min|aij| = 1.000e-02 max|aij| = 2.006e+01 ratio = 2.006e+03 > GM: min|aij| = 7.199e-01 max|aij| = 1.389e+00 ratio = 1.930e+00 > EQ: min|aij| = 5.209e-01 max|aij| = 1.000e+00 ratio = 1.920e+00 > 2N: min|aij| = 2.500e-01 max|aij| = 1.680e+00 ratio = 6.720e+00 > Constructing initial basis... > Size of triangular part is 766 > Solving LP relaxation... > GLPK Simplex Optimizer, v4.65 > 766 rows, 1019 columns, 15790 non-zeros > 0: obj = 2.904848487e+09 inf = 3.040e+02 (75) > 79: obj = 3.630095622e+09 inf = 4.441e-16 (0) > * 130: obj = 3.328774238e+09 inf = 7.881e-15 (0) > OPTIMAL LP SOLUTION FOUND > Integer optimization begins... > Long-step dual simplex will be used > Gomory's cuts enabled > MIR cuts enabled > Cover cuts enabled > Number of 0-1 knapsack inequalities = 95 > Clique cuts enabled > Constructing conflict graph... > Conflict graph has 182 + 70 = 252 vertices > + 130: mip = not found yet >= -inf (1; 0) > Cuts on level 0: gmi = 2; mir = 2; > Cuts on level 10: gmi = 2; mir = 2; > + 161: >>>>> 3.328774238e+09 >= 3.328774238e+09 0.0% (11; 0) > + 161: mip = 3.328774238e+09 >= tree is empty 0.0% (0; 21) > INTEGER OPTIMAL SOLUTION FOUND > Time used: 0.3 secs > Memory used: 12.2 Mb (12789041 bytes) > Model has been successfully processed > > # ========================================================== # > > *Gurobi 9.1.1 (win64) logging started Thu Mar 4 14:41:08 2021* > > Gurobi Optimizer version 9.1.1 build v9.1.1rc0 (win64) > Thread count: 2 physical cores, 4 logical processors, using up to 4 > threads > Optimize a model with 766 rows, 1021 columns and 15790 nonzeros > Variable types: 510 continuous, 511 integer (511 binary) > Coefficient statistics: > Matrix range [1e-02, 2e+01] > Objective range [6e+05, 4e+08] > Bounds range [1e+00, 1e+00] > RHS range [4e-02, 2e+01] > Found heuristic solution: objective 3.666169e+09 > Presolve removed 759 rows and 1012 columns > Presolve time: 0.03s > Presolved: 7 rows, 9 columns, 18 nonzeros > Found heuristic solution: objective 3.360309e+09 > Variable types: 0 continuous, 9 integer (9 binary) > > Root relaxation: cutoff, 2 iterations, 0.01 seconds > > Nodes | Current Node | Objective Bounds | Work > Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time > > 0 0 cutoff 0 3.3603e+09 3.3603e+09 0.00% - 0s > > Explored 0 nodes (2 simplex iterations) in 0.09 seconds > Thread count was 4 (of 4 available processors) > > Solution count 2: 3.36031e+09 3.66617e+09 > > Optimal solution found (tolerance 1.00e-04) > Best objective 3.360308547685e+09, best bound 3.360308547685e+09, gap > 0.0000% > Gurobi Optimizer version 9.1.1 build v9.1.1rc0 (win64) > Thread count: 2 physical cores, 4 logical processors, using up to 4 > threads > Optimize a model with 766 rows, 1021 columns and 15790 nonzeros > Coefficient statistics: > Matrix range [1e-02, 2e+01] > Objective range [6e+05, 4e+08] > Bounds range [1e+00, 1e+00] > RHS range [4e-02, 2e+01] > Iteration Objective Primal Inf. Dual Inf. Time > 0 3.3603085e+09 2.034244e+01 0.000000e+00 0s > 45 3.3603085e+09 0.000000e+00 0.000000e+00 0s > > Solved in 45 iterations and 0.01 seconds > * > * > Optimal objective 3.360308548e+09 > > ======================================================== > > Bests, > -- > João Flávio de Freitas Almeida > > > Em qui., 4 de mar. de 2021 às 14:20, Thiago Neves > <[email protected] <mailto:[email protected]>> escreveu: > > Thank you so much for the explanation Antti. > You are right, this seems more like a "design flaw" than a "bug". > I'm sorry for the misconception. > > Why does "eps" need to be so big (1e-3)? Is there a way to set a > fixed threshold in the command line (glpsol) or at least the 1e-3 > part? > > In the case (1), wouldn't it be better to choose max(l[q], l'[q])? > > Att, > > *Thiago H. Neves* > (31) 98608-0666 > > > > ---------- Forwarded message --------- > De: *Antti Lehtila* <[email protected] > <mailto:[email protected]>> > Date: qui., 4 de mar. de 2021 às 12:44 > Subject: Re: Solver delivers wrong answer when 2 constraints are close > To: <[email protected] <mailto:[email protected]>> > > > Hi, > > I think it works fully as documented, and so *per design*. Singleton > rows are treated as column bounds by the preprocessor. See > documentation > for *npp_implied_lower*: > *--------------- > * Processing implied column lower bound l'[q] includes the following > * cases: > * > * 1) if l'[q] < l[q] + eps, implied lower bound is redundant; > * > * 2) if l[q] + eps <= l[q] <= u[q] + eps, current column lower bound > * l[q] can be strengthened by replacing it with l'[q]. If in this > * case new column lower bound becomes close to current column > upper > * bound u[q], the column can be fixed on its upper bound; > * > * 3) if l'[q] > u[q] + eps, implied lower bound violates current > * column upper bound u[q], in which case the problem has no primal > * feasible solution. */ > *--------------- > The lower bound can have only a single value, but if you define > multiple > values for a column lower bound, they must of course be processed in > some order. In this case, the lower bound is first defined > l(q)=0, then > l'(q)=1, and finally l'(q)=1.0001. The third value for the bound > is thus > considered *redundant*, as per design, and so the second value l(q)=1 > remains in effect. This is because *eps* is defined as 1e-3 + 1e-6 * > fabs(q->lb)). > > I guess it may be a considered a design flaw, but I think it > should not > be called a bug, as it is working as designed and documented. > Besides, > I think one should use the Bounds section for bounds, instead of > using > multiple constraints for defining a single lower bound. > > Best, > Antti > _______________________ > On 04.03.2021 11:38, Domingo Alvarez Duarte wrote: > > > > Testing this problem I discover that if we change the order of > > constraint declarations it seems to give the expected answer as > stated > > by Thiago (what I think could be another bug). > > > > ==== > > > > /param min_bound default 0;/ > > /var x >= 0; > > > > minimize y: x;/ > > * > > */*s.t. PART_MIN_X: x >= 1 + min_bound;* > > / > > /*s.t. LIM_INF_X: x >= 1; > > * > > / > > /solve; > > display min_bound; > > display x; # EXPECTED RESULT: X == 1.0001 > > > > data; > > param min_bound := 1e-4; > > end;/ > > > > ==== > > > > Output: > > > > ==== > > > > x.val = 1.0001 > > > > ==== > > > > On 3/3/21 19:19, Thiago Neves wrote: > >> Hi. > >> I've found a strange behaviour in glpk which I don't know how > to fix > >> nor how to contour it. It seems like GLPK can't distinguish > >> constraints that differs from about 1e-4. > >> > >> Follows simple examples that explain and reproduce the problem.** > >> * > >> * > >> *The first model gives the desired answer (x = 1.0001):* > >> / > >> param min_bound default 0;/ > >> /var x >= 0; > >> > >> minimize y: x;/ > >> /* > >> s.t. PART_MIN_X: x >= 1 + min_bound;* > >> > >> solve; > >> display min_bound; > >> display x; # EXPECTED RESULT: X == 1.0001 > >> > >> data; > >> param min_bound := 1e-4; > >> end; > >> / > >> /_____________________________________/ > >> /OUTPUT:/ > >> /x.val = 1.0001/ > >> /_____________________________________ / > >> > >> *Now, if I add a second constraint "close" to the first one, the > >> solver will deliver an answer that is actually infeasible:* > >> > >> /param min_bound default 0;/ > >> /var x >= 0; > >> > >> minimize y: x;/ > >> > >> *s.t. LIM_INF_X: x >= 1; > >> > >> */*s.t. PART_MIN_X: x >= 1 + min_bound;* > >> > >> solve; > >> display min_bound; > >> display x; # EXPECTED RESULT: X == 1.0001 > >> > >> data; > >> param min_bound := 1e-4; > >> end;/ > >> /_____________________________________/ > >> /OUTPUT:/ > >> x.val = 1 > >> /_____________________________________ / > >> > >> *If I change the "min_bound" parameter to 1e-2, the second model > >> works as expected (x = 1.01):* > >> > >> /param min_bound default 0;/ > >> / > >> / > >> /var x >= 0; > >> > >> minimize y: x;/ > >> * > >> * > >> *s.t. LIM_INF_X: x >= 1; > >> > >> */*s.t. PART_MIN_X: x >= 1 + min_bound;* > >> > >> solve;/ > >> / > >> display x; # EXPECTED RESULT: X == 1.01 > >> > >> data; > >> param min_bound := 1e-2; > >> end;/ > >> /_____________________________________/ > >> /OUTPUT:/ > >> x.val = 1.01 > >> /_____________________________________ / > >> / > >> / > >> > >> Att, > >> > >> *Thiago H. Neves* > >> (31) 98608-0666 > >> > >