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: Andrew Makhorin
Subject: Re: Solver delivers wrong answer when 2 constraints are close
Date: Thu, 04 Mar 2021 20:19:04 +0300

On Thu, 2021-03-04 at 17:47 +0100, Heinrich Schuchardt wrote:
> On 3/4/21 4:44 PM, Antti Lehtila wrote:
> > 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
> 
> In this line an apostrophe is missing.
> 
>    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;
> 
> It is this strengthening that fails:
> 
> src/npp/npp3.c:567
> eps = (q->is_int ? 1e-3 : 1e-3 + 1e-8 * fabs(q->lb));
> 
> Set eps to 1E-5 and you are fine.
> 
> Or run with --nopresol.
> 
> @Andrew:
> Shouldn't 1E-5 be good enough?
> Why do we need eps > 0?


Both 1e-3 and 1e-5 are good enough.

If the result is sensitive to such small deviations, this only tells
that the model is badly formulated.


> 
> Best regards.
> 
> Heinrich
> 
> > *
> > *  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]