How can I write an if condition for my variable in GLPK?

Figen Güngör picture Figen Güngör · Mar 17, 2013 · Viewed 18.8k times · Source

Here is my full problem:

enter image description here

Information:

*Max. total investment: $125

*Pay-off is the sum of the units bought x pay-off/unit

*Cost per investment: Buy-in cost + cost/unit x number of units if you buy at least one unit

*The cost is sum of the costs per investment

Constraints:

*You may not invest in both 2 and 5.

*You may invest in 1 only if you invest at least one of 2 and 3.

*You must invest at least two of 3,4,5.

*You may not invest more than max number of units.

Problem: Maximize profit : pay-off - cost

 xi: # of units i ∈ {1,2,3,4,5}
 yi=1 if xi>0 else yi=0
 cost = sum{i in I} buyInCost_i * yi + cost-unit_i*xi
 pay-off = sum{i in I} (pay-off/unit)_i*xi
 profit = pay-off - cost

 Maximize profit

 Subject to

 y2+y5 <= 1
 y1<= y2+y3
 y3+y4+y5 >= 2
 x1<=5, x2<=4, x3<=5, x4<=7, x5<=3
 cost<=125

Here is my question:

For example I have this binary variable y

 yi=1 if xi>0 else yi=0  and i ∈ {1,2,3,4,5}

I declared i as a data set

 set I;

 data;

 set I := 1 2 3 4 5;

I don't know how to add if else condition to y variable in glpk. Can you please help me out?

My modelling :

 set I;

 /*if x[i]>0 y[i]=1 else y[i]=0 ?????*/
 var y{i in I}, binary;

 param a{i in I};
 /* buy-in cost of investment i */

 param b{i in I};
 /* cost per unit of investment i */

 param c{i in I};
 /* pay-off per unit of investment i */

 param d{i in I};
 /* max number of units of investment i */

 var x{i in I} >=0;
 /* Number of units that is bought of investment i */

 var po := sum{i in I} c[i]*x[i];

 var cost := sum{i in I} a[i]*y[i] + b[i]*x[i];

 maximize profit: po-cost;

 s.t. c1: y[2]+y[5]<=1;
 s.t. c2: y[1]<y[2]+y[3];
 s.t. c3: y[3]+y[4]+y[5]>=2;
 s.t. c4: x[1]<=5 
     x[2]<=4
     x[3]<=5
     x[4]<=7
     x[5]<=3;

 s.t. c5: cost <=125;
 s.t. c6{i in I}: M * y[i] > x[i];   // if condition of y[i] 

 set I := 1 2 3 4 5;
 param a :=
1 25
2 35
3 28
4 20
5 40;

 param b :=
1 5
2 7
3 6
4 4
5 8;

 param c :=
1 15
2 25
3 17
4 13
5 18;

 param d :=
1 5
2 4
3 5
4 7
5 3;

 param M := 10000;

I am getting this syntax error:

      problem.mod:21: syntax error in variable statement 
      Context: ...I } ; param d { i in I } ; var x { i in I } >= 0 ; var po :=
      MathProg model processing error

Answer

Nicolas Grebille picture Nicolas Grebille · Mar 18, 2013

You can't directly do that (there is no way to write 'directly' an if constraint in a LP).

However, there are workarounds for this. For example, you can write:

M * yi > xi

where M is a large constant (greater than any value of xi).

This way:

  • if xi > 0, then the constraint is equivalent to yi > 0, that is yi == 1 since yi is binary (if M is large enough).
  • if xi == 0, then the constraint is always verified, and yi will be equal to 0 since your objective is increasing with yi and you are minimizing.

in both case, the constraint is equivalent to the if test.