LP file format
The lp-format input syntax is a set of algebraic expressions and "int"
declarations in the following order:
<objective function>
<constraint>*
<declaration>*
where:
- <objective function> is a linear combination of variables, ending
with a semicolon, optionally preceded by "max: " or "min: " to
indicate whether you want it to be minimized or maximized. The case
is not important, "Max:" or "MAX:" will work as well. Maximization
is the default. Alternatives are minimise, minimize, maximise, Maximize
- <constraint> is an optional constraint name followed by a colon plus
a linear combination of variables and constants or (just one)
constraint name followed by a colon (a range) or (just one) variable
name without a colon (a bound), followed by a relational operator,
followed again by a linear combination of variables and constants,
ending with a semicolon. The relational operator can be any of the
following: "<" "<=" "=" ">" ">=". There is no semantic difference
between "<" and "<=" nor between ">" and ">=" (even for integer
variables!).
- <declaration> is of one of the forms:
To define variables as integer:
"int"
var [","] var [","] var ... ";"
To define variables as semi-cont:
"sec"
var [","] var [","] var ... ";"
To define Special Ordered Sets (SOS):
"sos"
[sosdescr:] [","] var[:weight] [","] var[:weight] [","] var[:weight] ... "<[=]" sostype[:sosorder] ";" ...
or:
"sosx"
[sosdescr:] var[:weight] [","] var[:weight] [","] var[:weight] ... ";" ...
- A var must start with a letter (either upper or lower case), and may
contain any number of additional letters, numerals, or characters
from this list: _[]{}/.&#$%~'@^
- Comments can be used with the /* */ syntax, just like in C.
It can be put anywhere in the file and even over multiple lines.
lp_solve 4.0.1.11 and newer also supports the C++ line comment //
- Empty lines are also allowed.
EXAMPLES
The simple problem:
x1 >= 1
x2 >= 1
x1 + x2 >= 2
minimize x1 + x2 (= maximize -(x1 + x2)), with x1 integer
Can be written as follows in lp-format:
-x1 -x2;
/* or min: x1 + x2; */
x1 >= 1;
x2 >= 1;
x1 + x2 >= 2;
int x1;
The correct result for (x1, x2) is of course (1, 1).
If you want to give a name to a restriction then begin the line with the name and a colon.
For example:
-x1 -x2;
/* or min: x1 + x2; */
x1 >= 1;
x2 >= 1;
myrow: x1 + x2 >= 2;
int x1;
Note that for bounds on variables, you should not put labels before them.
This because lp_solve then makes an extra restriction of this.
If you don't put a label before single variables then lp_solve doesn't have to create
an extra row for bounds on variables which is more performant.
So it is better to write:
x1 >= 1;
Than
r_x1: x1 >= 1;
Note that this is only for single variables. So
myrow: x1 + x2 >= 2;
Is as performant as
x1 + x2 >= 2;
Also the variable can have a constant.
For example:
2 x1 >= 2;
Is automatically translated to
x1 >= 1;
by lp_solve, so no extra restriction, but a more performant bound restriction.
From the moment there is more than one variable in a constraint, lp_solve can only create
a restriction (extra row) for this.
Sometimes there is a lower and upper bound on a variable. This can be written in several ways:
x1 >= 1;
x1 <= 3;
It doesn't matter if the lower bound comes first or not. They are also not required to be together.
Another way to write this is:
1 <= x1 <= 3;
Or
3 >= x1 >= 1;
These bounds on variables are handled by lp_solve in a special way so that no extra restrictions
(rows) are created, which will lead to more performance.
Also on restrictions there can be both a lower and upper value. They are called ranges.
For example:
myrow: x1 + x2 >= 2;
Suppose that the same restriction should also be <= 6, then this could be written as:
myrowmin: x1 + x2 >= 2;
myrowmax: x1 + x2 <= 6;
However then there are two rows in the model which makes it larger and harder to solve.
lp_solve can handle this in one row so that the model is smaller and it will solve more quickly.
This will only be done if the modelling is done in one of the following ways:
myrow: x1 + x2 >= 2;
myrow: <= 6;
Or
myrow: x1 + x2 <= 6;
myrow: >= 2;
Or
myrow: 6 >= x1 + x2 >= 2;
Or
myrow: 2 <= x1 + x2 <= 6;
Or
6 >= x1 + x2 >= 2;
Or
2 <= x1 + x2 <= 6;
Note that there must be a row label if the construction
label: op constant
is used. This requirement does not count if the min and max restriction is put on one line.
Also the range must come after the constraint definition.
Example with integer variables:
min: -x1 -2 x2 +0.1 x3 +3 x4;
r_1: +x1 +x2 <= 5;
r_2: +2 x1 -x2 >= 0;
r_3: -x1 +3 x2 >= 0;
r_4: +x3 +x4 >= 0.5;
x3 >= 1.1;
int x3, x4;
See integer variables for a description about integer variables.
Example with semi-continuous variables:
max: x1 + 2x2 - 4x3 -3x4;
x1 + x2 <= 5;
2x1 - x2 >= 0;
-x1 + 3x2 >= 0;
x3 + x4 >= .5;
x3 >= 1.1;
x3 <= 10;
sec x3, x4;
See semi-continuous variables for a description about semi-continuous variables.
Examples with Special Ordered Sets (SOS):
min: -x1 -x2 -3 x3 -2 x4 -2 x5;
c1: -x1 -x2 +x3 +x4 <= 30;
c2: +x1 +x3 -3 x4 <= 30;
x1 <= 40;
x2 <= 1;
x5 <= 1;
sos
SOS1: x1, x2, x3, x4 <= 2;
SOS2: x2, x3, x4, x5 <= 3;
Alternative:
min: -x1 -x2 -3 x3 -2 x4 -2 x5;
c1: -x1 -x2 +x3 +x4 <= 30;
c2: +x1 +x3 -3 x4 <= 30;
x1 <= 40;
x2 <= 1;
x5 <= 1;
sos2
SOS1: x1, x2, x3, x4;
SOS2: x2, x3, x4, x5;
With SOS weights:
min: -x1 -x2 -3 x3 -2 x4 -2 x5;
c1: -x1 -x2 +x3 +x4 <= 30;
c2: +x1 +x3 -3 x4 <= 30;
x1 <= 40;
x2 <= 1;
x5 <= 1;
sos
SOS1: x1:5, x2:9, x3:12, x4:17 <= 2:3;
SOS2: x2:9, x3:12, x4:17, x5:21 <= 2:3;
See Special Ordered Sets (SOS) for a description about Special Ordered Sets.
|