0

With lp_solve I need to constrain the ratio of two linear functions to be non-negative:

min: 13.21 y0 + 27.46 y1 + 35.66 y2 + 89.21 y3 + 60.69 y4;

y0 + y1 + y2 + y3 + y4 >= 50000;

y0 <= 69148;
y1 <= 25460;
y2 <= 34020;
y3 <= 69873;
y4 <= 737299;

/* Spezification */
(-0.275 y0 + 0.15 y1 + 0.15 y2 + 0.236 y3 + 0.14745 y4) / (-0.175 y0 + 0.05 y1 + 0.05 y2 + 0.136 y3 + 0.04745 y4) >= 0;

But lp_solve does not provide parentheses. Is it possible to solve it, so I don't need parentheses, or is this a general problem with lp_solve?

josliber
  • 43,891
  • 12
  • 98
  • 133
ABSimon
  • 651
  • 1
  • 6
  • 18

2 Answers2

4

You are trying to add a constraint of the following form to a linear program:

(-0.275 y0 + 0.15 y1 + 0.15 y2 + 0.236 y3 + 0.14745 y4) / (-0.175 y0 + 0.05 y1 + 0.05 y2 + 0.136 y3 + 0.04745 y4) >= 0;

For notational simplicity, I'll define A = (-0.275 y0 + 0.15 y1 + 0.15 y2 + 0.236 y3 + 0.14745 y4) and B = (-0.175 y0 + 0.05 y1 + 0.05 y2 + 0.136 y3 + 0.04745 y4). Your constraint is therefore:

A / B >= 0

This means one of the following two conditions must hold:

  1. A >= 0 and B >= 0
  2. A <= 0 and B <= 0

This introduces a non-convexity in your formulation, because points (A, B) = (4, 4) and (A, B) = (-2, -6) are both feasible, but their midpoint (A, B) = (1, -1) is not feasible. Because your feasible set is non-convex, it is actually provably impossible to model your situation using a linear program with all continuous variables as you have tried to do in your code.

You will need to introduce a binary variable into your formulation to model this non-convexity. A natural way to model this would be to make binary variable z equal 1 if A >= 0 and B >= 0 and to make z equal 0 if A <= 0 and B <= 0. Then you could introduce the following constraints (here M is a large positive constant):

A <= Mz
B <= Mz
A >= M(z-1)
B >= M(z-1)
z binary

If z=0, then the constraints give us -M <= A <= 0 and -M <= B <= 0, while if z=1, then the constraints give us 0 <= A <= M and 0 <= B <= M. If the selected value of M is sufficiently large, this will capture your situation.

josliber
  • 43,891
  • 12
  • 98
  • 133
  • Hello josliber, thank you for your help. I have problems get a running example. I try this. [code] A = -0.275 y0 + 0.15 y1 + 0.15 y2 + 0.236 y3 + 0.14745 y4; B = -0.175 y0 + 0.05 y1 + 0.05 y2 + 0.136 y3 + 0.04745 y4; A <= Mz; B <= Mz; A >= M(z-1); B >= M(z-1); z binary; [/code] But I get parse error. I do not understand the logic in detail... – ABSimon Apr 29 '16 at 22:03
  • @ABSimon `M` should be replaced with a large number, like 1000000. – josliber Apr 29 '16 at 22:33
  • Hello josliber, I need also to place the parentheses in "A >= 1000000(z-1)" and "B >= 1000000(z-1)". I think I get then "A >= 1000000 z - 1000000" and "B >= 1000000 z - 1000000". In total I have then the workaround "A <= 1000000 z; B <= 1000000 z; A >= 1000000 z - 1000000; B >= 1000000 z - 1000000; bin z;" instead of "A / B >= 0"? Thank you! I think it is a big help vor every lp_solve beginner :) – ABSimon Apr 30 '16 at 08:48
0

Your solution is well formulated, and lpsolve solved fine. But the results may not be what you would expect. For example, I got: z = 0 and x187 = 0 (A=B=0). The thing is that A and B are expressions depending only of x187, so you should simplify that division expression! The chosen big M, should be smaller?

Model name:  'model build from GLP-Solve' - run #1    
Objective:   Minimize(R0)

SUBMITTED
Model size:       12 constraints,      53 variables,          311 non-zeros.
Sets:                                   0 GUB,                  0 SOS.

Using DUAL simplex for phase 1 and PRIMAL simplex for phase 2.
The primal and dual simplex pricing strategy set to 'Devex'.


Relaxed solution       276710632.306 after         23 iter is B&B base.

Feasible solution      276710632.306 after         23 iter,         0 nodes (gap 0.0%)

Optimal solution       276710632.306 after         23 iter,         0 nodes (gap 0.0%).

Excellent numeric accuracy ||*|| = 0

 MEMO: lp_solve version 5.5.2.0 for 64 bit OS, with 64 bit REAL variables.
      In the total iteration count 23, 17 (73.9%) were bound flips.
      There were 0 refactorizations, 0 triggered by time and 0 by density.
       ... on average 6.0 major pivots per refactorization.
      The largest [LUSOL v2.2.1.0] fact(B) had 13 NZ entries, 1.0x largest basis.
      The maximum B&B level was 1, 0.5x MIP order, 1 at the optimal solution.
      The constraint matrix inf-norm is 1e+06, with a dynamic range of 6.39386e+08.
      Time to load data was 0.001 seconds, presolve used 0.000 seconds,
       ... 0.000 seconds in simplex solver, in total 0.001 seconds.

If we remove the A, B and z restrictions we obtain the same results:

Model name:  'model build from GLP-Solve' - run #1    
Objective:   Minimize(R0)

SUBMITTED
Model size:        6 constraints,      50 variables,          299 non-zeros.
Sets:                                   0 GUB,                  0 SOS.

Using DUAL simplex for phase 1 and PRIMAL simplex for phase 2.
The primal and dual simplex pricing strategy set to 'Devex'.


Optimal solution       276710632.306 after         22 iter.

Excellent numeric accuracy ||*|| = 0

 MEMO: lp_solve version 5.5.2.0 for 64 bit OS, with 64 bit REAL variables.
      In the total iteration count 22, 17 (77.3%) were bound flips.
      There were 0 refactorizations, 0 triggered by time and 0 by density.
       ... on average 5.0 major pivots per refactorization.
      The largest [LUSOL v2.2.1.0] fact(B) had 7 NZ entries, 1.0x largest basis.
      The constraint matrix inf-norm is 1, with a dynamic range of 639.386.
      Time to load data was 0.002 seconds, presolve used 0.001 seconds,
       ... 0.001 seconds in simplex solver, in total 0.004 seconds.
Helio
  • 3,322
  • 1
  • 14
  • 23
  • thank you. With "A >= -1000 ; B >= -1000 ;" A and B will be calculated. But the solution still does not make any effect in the results. Is it theoretically possible to repalce a division with something like this? A >= -1000; B >= -1000; A <= 1000 z; B <= 1000 z; A >= 1000 z - 1000; B >= 1000 z - 1000; bin z; I would appreciate any help. – ABSimon May 02 '16 at 20:35