Variable logical bound

Dear All,

using the following
subject to LL {j in POP}: pl[j] * Use[j] <= p[j];

The variable can not be lower than pl, but it can be zero.

var Use {POP} binary;

Gurobi solves to optimality, no issue reported, but some values are below pl (and above 0). Can you see anything wrong? Thank you.

1 Like

I just figured it out:
subject to LL {j in POP}: pl[j] <= p[j] or 0 == p[j];

1 Like

Hi @Milan, in this case the logical constraint as numerical benefits over the other approach since it can avoid numerical issues.

When you had the Use variables, what were the magnitude of the violations? Typically that would be a bug, but if the value of pl[j] is high, then pl[j] * Use[j] <= p[j] can result in p[j] lower than pl[j] since there is integrality tolerance in Gurobi that allows it to be something like 0.99999 which when multiplied by a large number would allow p[j] to be smaller than pl[j].

Thank you for your reply. I have attached the .mod and .dat files (a small example). I tested with Gurobi and COPT. The first approach (logical variable) provides:

Gurobi 10.0.1: Gurobi 10.0.1: optimal solution; objective 12.48871853
0 simplex iterations
6 barrier iterations
1 branching nodes

p [*] :=
1 0.0000
2 0.0224
3 0.4665
4 0.5111
;

The second approach satisfies the min limits (0.05):
Gurobi 10.0.1: Gurobi 10.0.1: optimal solution; objective 12.47575482
16 simplex iterations
1 branching nodes
absmipgap=3.24048e-05, relmipgap=2.59742e-06
Gain = 12.4758

p [*] :=
1 0.0000
2 0.0500
3 0.4242
4 0.5258
;

I would appreciate any advice on this. COPT and GUROBI provided identical results.

Thank you, Milan

osq.dat (292 Bytes)
osq.mod (518 Bytes)

The version with

subject to LL {j in POP}: pl[j] <= p[j] or 0 == p[j];

specifies that either p[j]=0 or p[j]>=pl[j]. Gurobi’s solution satisfies this requirement, with p[1] equal to 0 and p[2], p[3], and p[4] equal to 0.05 or larger. The other version has

var Use {POP} binary;
subject to LL {j in POP}: pl[j] * Use[j] <= p[j];

which specifies that either p[j]>=0 (when Use[j]=0) or p[j]>=pl[j] (when Use[j]=1) — which is not the same thing. To get the same effect as the previous formulation, you should modify constraints LL and LU as follows:

var Use {POP} binary;
subject to LL {j in POP}: p[j] >= Use[j] * pl[j];
subject to LU {j in POP}: p[j] <= Use[j] * pu[j];

Here you can see that either p[j]>=0 and p[j]<=0, hence pj[j]=0 (when Use[j]=0) or p[j]>=pl[j] and p[j]<=pu[j] (when Use[j]=0).

Thank you very much for your help. Indeed everything works now. Given the specifics of this problem, which of the two approaches should be preferred?

I prefer the approach that uses the or operator, because it expresses the constraint more clearly.

You might want to experiment with the other approach, just to see if it’s noticeably faster with the solver you are using. Sometimes, different formulation approaches cause the problem to be sent to the solver in different ways, which can possibly make a difference in solve times. I would only recommend this if you have trouble with your solve taking a very long time, however.