This file is indexed.

/usr/share/doc/lp-solve-doc/Presolve.htm is in lp-solve-doc 5.5.0.13-7build2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
	<HEAD>
		<TITLE>Presolve</TITLE>
		<style TYPE="text/css"> BODY { font-family:verdana,arial,helvetica; margin:0; }
	</style>
	</HEAD>
	<BODY>
		<TABLE STYLE="TABLE-LAYOUT:fixed" class="clsContainer" CELLPADDING="15" CELLSPACING="0"
			WIDTH="100%" BORDER="0" ID="Table1">
			<TR>
				<TD VALIGN="top">
<h1 align="left"><u>Presolve</u></h1>
<P>Presolve is a preprocess of the lp-model. It looks for ways to simplify it.
For example it can delete unused variables and restrictions. Substitute fixed variable values by a
constant and so on. The result is a new model that is less complex than the original model and likely solves faster.
<br>
The result of presolve can be that there are less variables and/or constraints in the presolved model.
</P>

<p>
Presolve is not active by default. It must specifically being enabled via the API call <A href="set_presolve.htm">set_presolve</A>.<br>
<br>
Different presolve options are possible.<br>
The more are chosen, the more presolve can be done and the model could me made simpler thus solved faster, but also presolve takes more time.
Presolve will most of the time result in a netto time that is faster than without, but can also result in a slower time.
So it is up to the user to decide when and which presolve to use on specific models. There is no general presolve option applicable for all models.
</p>

<p>
A simple example:
</p>

<pre>
max: x1 + x2 + x3;

r1: x2 = 2;
r2: x1 + x2 &lt;= 6;
r3: x1 - 2 x3 &gt;= 2;
r4: x2 + 3 x3 &lt;= 5;
</pre>

<p>
Row r1 is a constraint on one variable. Presolve can detect this and convert it to a bound on that variable.
For this, presolve of rows must be activated:
</p>

<pre>
lp_solve model.lp -wlp con -S1 -wafter -presolverow
</pre>

<pre>
/* Objective function */
max: +x1 +x2 +x3;

/* Constraints */
r2: +x1 +x2 &lt;= 6;
r3: +x1 -2 x3 &gt;= 2;
r4: +x2 +3 x3 &lt;= 5;

/* Variable bounds */
x2 = 2;
</pre>

<p>
And even this model can be presolved further.<br>
When presolve of columns is active, variables can be eliminated from the model.
</p>

<pre>
lp_solve model.lp -wlp con -S1 -wafter -presolverow -presolvecol
</pre>

<pre>
/* Objective function */
max: +x1 +x3 +2;

/* Constraints */
r3: +x1 -2 x3 &gt;= 2;

/* Variable bounds */
x1 &lt;= 4;
x3 &lt;= 1;
</pre>

<p>
Note the -wafter option. If this option is not specified, the original model is printed.
The reason for this is the moment that write_lp is called. The effect of presolve happens
when a solve is done. If write_lp is called before solve then the original model is given.
If called after solve then the presolved model is.
</p>

<p>
As previously stated, presolve can result in removal of variables and/or constraints.
For some models, presolve can even find the solution of the model.<br>
<br>
For constraints that are removed, all information of them are lost. Presolve has removed them from the
matrix and cannot retrieve any information of them anymore. The number of rows is decreased by the number of
constraints deleted.
<A HREF="get_Nrows.htm">get_Nrows</A> does not return the original number of rows, but the number of rows in the
new model.<br>
<br>
Variables that are removed from the matrix result in less columns in the model.
<A href="get_Ncolumns.htm">get_Ncolumns</A> does not return the original number of columns, but the number of
columns in the new model.<br>
<br>
However the information of the removed variables is not lost. Only variables that result in a fixed value are
removed by presolve and their value is remembered at that time.
</p>

<p>
Example in C:
</p>

<pre>
#include &lt;stdio.h&gt;

#include "lp_lib.h"

int main(void)
{
# if defined ERROR
#  undef ERROR
# endif
# define ERROR() { fprintf(stderr, "Error\n"); exit(1); }
  lprec *lp;

  if ((lp=make_lp(0, 3)) == NULL)
    ERROR();
  set_col_name(lp, 1, "x1");
  set_col_name(lp, 2, "x2");
  set_col_name(lp, 3, "x3");
  set_maxim(lp);
  if (!str_add_constraint(lp, "0 1 0", EQ, 2))
    ERROR();
  set_row_name(lp, 1, "R1");
  if (!str_add_constraint(lp, "1 1 0", LE, 6))
    ERROR();
  set_row_name(lp, 2, "R2");
  if (!str_add_constraint(lp, "1 0 -2", GE, 2))
    ERROR();
  set_row_name(lp, 3, "R3");
  if (!str_add_constraint(lp, "0 1 3", LE, 5))
    ERROR();
  set_row_name(lp, 4, "R4");
  if (!str_set_obj_fn(lp, "1 1 1"))
    ERROR();

  write_LP(lp, stdout);
  set_presolve(lp, PRESOLVE_ROWS + PRESOLVE_COLS, 0);
  solve(lp);
  print_objective(lp);
  print_solution(lp, 1);
  print_constraints(lp, 1);

  print_duals(lp);

  write_LP(lp, stdout);

  delete_lp(lp);

}
</pre>

<p>
This gives:
</p>

<pre>
/* Objective function */
max: +x1 +x2 +x3;

/* Constraints */
R1: +x2 = 2;
R2: +x1 +x2 &lt;= 6;
R3: +x1 -2 x3 &gt;= 2;
R4: +x2 +3 x3 &lt;= 5;

Model name:  '' - run #1
Objective:   Maximize(R0)

SUBMITTED
Model size:        4 constraints,       3 variables,            7 non-zeros.
Sets:                                   0 GUB,                  0 SOS.

Presolve O:1 -&gt; Reduced rows:    3, cols:    1 --- changed bnds:    4, Ab:    0.

PRESOLVE             Elimination loops performed.......... O3:M3:I5
                   1 empty or fixed variables............. REMOVED.
                   3 empty or redundant constraints....... REMOVED.
                   4 bounds............................... TIGHTENED.
                     [           +2 &lt; Z &lt; +7           ]

REDUCED
Model size:        1 constraints,       2 variables,            2 non-zeros.
Sets:                                   0 GUB,                  0 SOS.
Row-types:         0 LE,                1 GE,                   0 EQ.

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


Optimal solution                   7 after          0 iter.

Excellent numeric accuracy ||*|| = 0

 MEMO: lp_solve version 5.5.0.13 for 32 bit OS, with 64 bit REAL variables.
      In the total iteration count 0, 0 (100.0%) were bound flips.
      There were 0 refactorizations, 0 triggered by time and 0 by density.
       ... on average 0.0 major pivots per refactorization.
      The largest [etaPFI v1.4] fact(B) had 0 NZ entries, 0.0x largest basis.
      The constraint matrix inf-norm is 2, with a dynamic range of 2.
      Time to load data was 0.235 seconds, presolve used 0.140 seconds,
       ... 0.047 seconds in simplex solver, in total 0.422 seconds.

Value of objective function: 7

Actual values of the variables:
x1                              4
x2                              2
x3                              1

Actual values of the constraints:
R3                              2

Objective function limits:
                                 From            Till       FromValue
x1                                  0          1e+030         -1e+030
x3                                  0          1e+030         -1e+030

Dual values with from - till limits:
                           Dual value            From            Till
R3                                  0         -1e+030          1e+030
x1                                  1               4          1e+030
x3                                  1         -1e+030               1
/* Objective function */
max: +x1 +x3 +2;

/* Constraints */
R3: +x1 -2 x3 &gt;= 2;

/* Variable bounds */
x1 &lt;= 4;
x3 &lt;= 1;
</pre>

<p>
The result only shows values of contraint R3, the one that is kept.
The information of the removed constraints is no longer there.<br>
The variable result however is not lost. x2 is removed by presolve, but its value is still known.
On the other hand, note also that the variable does not appear in the sensitivity result.
</p>

<p>
Almost all API calls return information of the presolved model.
<A HREF="get_Nrows.htm">get_Nrows</A> and <A href="get_Ncolumns.htm">get_Ncolumns</A> return the number of
rows and columns of the presolved model. To know the original values,
<A href="get_Norig_rows.htm">get_Norig_rows</A> and <A HREF="get_Norig_columns.htm">get_Norig_columns</A> must be
used:
</p>

<pre>
printf("get_Nrows: %d\n", get_Nrows(lp));
printf("get_Norig_rows: %d\n", get_Norig_rows(lp));
printf("get_Ncolumns: %d\n", get_Ncolumns(lp));
printf("get_Norig_columns: %d\n", get_Norig_columns(lp));

get_Nrows: 1
get_Norig_rows: 4
get_Ncolumns: 2
get_Norig_columns: 3
</pre>

<p>
To retrieve the variable data of all variables, including the presolved variables, API call
<a href="get_primal_solution.htm">get_var_primalresult</a> must be used.
This is the only call available to get all information.<br>
The following code prints the values of all variables:
</p>

<pre>
int column, Nrows, Ncolumns;

Ncolumns = get_Norig_columns(lp);
Nrows = get_Norig_rows(lp);
for (column = 1; column &lt;= Ncolumns; column++) {
  printf("x%d: %f\n", column, get_var_primalresult(lp, Nrows + column));
}
</pre>

<p>
With result:
</p>

<pre>
x1: 4.000000
x2: 2.000000
x3: 1.000000
</pre>

<p>
<a href="get_primal_solution.htm">get_var_primalresult</a> also returns information about rows.<br>
The following code prints the results of all rows:
</p>

<pre>
int row, Nrows;

Nrows = get_Norig_rows(lp);

for (row = 1; row &lt;= Nrows; row++) {
  printf("R%d: %f\n", row, get_var_primalresult(lp, row));
}
</pre>

<p>
With result:
</p>

<pre>
R1: 0.000000
R2: 0.000000
R3: 2.000000
R4: 0.000000
</pre>

<p>
You could think here that a result for all original rows are returned, but this is not the case.
Only the result of constraints that were kept in the model are given. The other rows will return 0!
</p>

<p>
There is also a possibility to know which rows and columns are removed from the model.
<a href="get_orig_index.htm">get_orig_index</a> can be used for that.<br>
The following code demonstrates it:
</p>

<pre>
int row, Nrows;
int column, Ncolumns;

Ncolumns = get_Ncolumns(lp);
Nrows = get_Nrows(lp);

for (row = 1; row &lt;= Nrows; row++)
  printf("row %d was row R%d\n", row, get_orig_index(lp, row));

for (column = 1; column &lt;= Ncolumns; column++)
  printf("column %d was column x%d\n", column, get_orig_index(lp, Nrows + column));
</pre>

<p>
With result:
</p>

<pre>
row 1 was row R3
column 1 was column x1
column 2 was column x3
</pre>

<p>
So from this it can be determined that only row R3 and columns x1 and x3 are kept in the model.
The others are removed by presolve.
</p>

<p>
Again note that all other API calls return information about the presolved model.
So for example <a href="get_primal_solution.htm">get_ptr_primal_solution</a> must be used like this:
</p>

<pre>
int row, Nrows;
int column, Ncolumns;
double *pv;

get_ptr_primal_solution(lp, &amp;pv);

Ncolumns = get_Ncolumns(lp);
Nrows = get_Nrows(lp);

for (row = 1; row &lt;= Nrows; row++)
  printf("row %d: %f\n", row, pv[row]);

for (column = 1; column &lt;= Ncolumns; column++)
  printf("column %d: %f\n", column, pv[Nrows + column]);
</pre>

<p>
With result:
</p>

<pre>
row 1: 2.000000
column 1: 4.000000
column 2: 1.000000
</pre>

<p>
Row and column names of the original model can be obtained via
<a href="get_row_name.htm">get_origrow_name</a> and <a href="get_col_name.htm">get_origcol_name</a>:
</p>

<pre>
int row, Nrows;
int column, Ncolumns;

Ncolumns = get_Norig_columns(lp);
Nrows = get_Norig_rows(lp);

for (row = 1; row &lt;= Nrows; row++)
 printf("row %d: %s\n", row, get_origrow_name(lp, row));

for (column = 1; column &lt;= Ncolumns; column++)
 printf("column %d: %s\n", column, get_origcol_name(lp, column));
</pre>

<p>
With result:
</p>

<pre>
row 1: R1
row 2: R2
row 3: R3
row 4: R4
column 1: x1
column 2: x2
column 3: x3
</pre>

<p>
Row and column names of the presolved model can be obtained via
<a href="get_row_name.htm">get_row_name</a> and <a href="get_col_name.htm">get_col_name</a>:
</p>

<pre>
int row, Nrows;
int column, Ncolumns;

Ncolumns = get_Ncolumns(lp);
Nrows = get_Nrows(lp);

for (row = 1; row &lt;= Nrows; row++)
 printf("row %d: %s\n", row, get_row_name(lp, row));

for (column = 1; column &lt;= Ncolumns; column++)
 printf("column %d: %s\n", column, get_col_name(lp, column));
</pre>

<p>
With result:
</p>

<pre>
row 1: R3
column 1: x1
column 2: x3
</pre>
				</TD>
			</TR>
		</TABLE>
	</BODY>
</html>