help-glpk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Solver delivers wrong answer when 2 constraints are close


From: Domingo Alvarez Duarte
Subject: Re: Solver delivers wrong answer when 2 constraints are close
Date: Fri, 5 Mar 2021 10:13:26 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0

Looking through the code I can see that it seems to be a mismatch in checking for lower/upper bound in other places too (see bellow).

Also testing in AMPL it only returns 'x = 1' for 'min_bound = 1e-06', and it works for 'min_bound = 1e-05' and return 'x = 1.00001'.

===

int npp_implied_value(NPP *npp, NPPCOL *q, glp_double s)
{

...

      /* check current column lower bound */
      if (q->lb != -GLP_DBL_MAX)
      {  eps = (q->is_int ? GLP_NPP_EPS5 : GLP_NPP_EPS_5_8_fabs(q->lb));
...

      /* check current column upper bound */
      if (q->ub != +GLP_DBL_MAX)
      {  eps = (q->is_int ? GLP_NPP_EPS5 : GLP_NPP_EPS_5_8_fabs(q->ub));
...

}

...

int npp_implied_lower(NPP *npp, NPPCOL *q, glp_double l)
{     /* process implied column lower bound */
...

      /* check current column lower bound */
      if (q->lb != -GLP_DBL_MAX)
      {  eps = (q->is_int ? GLP_NPP_EPS : GLP_NPP_EPS_3_6_fabs(q->lb));
...

      /* check current column upper bound */
      if (q->ub != +GLP_DBL_MAX)
      {  eps = (q->is_int ? GLP_NPP_EPS5 : GLP_NPP_EPS_5_8_fabs(q->ub));
...

}

...

int npp_implied_upper(NPP *npp, NPPCOL *q, glp_double u)
{     int ret;
...

      /* check current column upper bound */
      if (q->ub != +GLP_DBL_MAX)
      {  eps = (q->is_int ? GLP_NPP_EPS : GLP_NPP_EPS_3_6_fabs(q->ub));
...

      /* check current column lower bound */
      if (q->lb != -GLP_DBL_MAX)
      {  eps = (q->is_int ? GLP_NPP_EPS5 : GLP_NPP_EPS_5_8_fabs(q->lb));
...

}

===

Cheers !

On 4/3/21 18:19, Thiago Neves wrote:
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 <antti.lehtila@vtt.fi>
Date: qui., 4 de mar. de 2021 às 12:44
Subject: Re: Solver delivers wrong answer when 2 constraints are close
To: <help-glpk@gnu.org>


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
>>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]