docs/ 0000755 0001750 0001750 00000000000 11306036626 010455 5 ustar rene rene docs/5.5/ 0000755 0001750 0001750 00000000000 11306036627 010765 5 ustar rene rene docs/5.5/set_basisvar.htm 0000644 0001750 0001750 00000003573 11306036626 014173 0 ustar rene rene
set_basisvarThis is an internal function that has been published for special purposes. It should generally not be used. int set_basisvar(lprec *lp, int basisPos, int enteringCol); Return Value Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI basisPos enteringCol Remarks Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI |
is_semicontGets the type of the variable. semi-continuous or not. unsigned char is_semicont(lprec *lp, int column); Return Value is_semicont returns TRUE (1) if the variable is set as semi-continuous, FALSE (0)
otherwise. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI column The column number of the variable that must be checked. It must be between 1 and the number of columns in the lp. Remarks The is_semicont function returns if a variable must be semi-continuous or not. Default a variable is not semi-continuous. See semi-continuous variables for a description about semi-continuous variables. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_semicont |
get_Norig_rowsReturns the number of original rows (constraints) in the lp. int get_Norig_rows(lprec *lp); Return Value get_Norig_rows returns the number of original rows (constraints) in the lp. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The get_Norig_rows function returns the number of original rows (constraints) in the lp. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_Nrows, get_Lrows, get_Ncolumns, get_Norig_columns, get_orig_index, get_lp_index |
print_strPrints a string. void print_str(lprec *lp, char *str); Return Value print_str has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI str The string to print Remarks
The print_str function prints a string. By default, the output is stdout. However
this can be changed via a call to set_outputstream, set_outputfile. Example
See Also delete_lp, free_lp, make_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, print_objective, print_solution, print_constraints, print_duals, print_scales, print_tableau, set_outputstream, set_outputfile, print_debugdump |
dualize_lpCreate the dual of the current model. unsigned char dualize_lp(lprec *lp); Return Value Returns TRUE if succeeded. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks
Example
See Also make_lp, copy_lp, delete_lp, free_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI |
set_bb_depthlimitSets the maximum branch-and-bound depth. void set_bb_depthlimit(lprec *lp, int bb_maxlevel); Return Value set_bb_depthlimit has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI bb_maxlevel Specifies the maximum branch-and-bound depth. A positive value means that the depth is absoluut. A negative value means a relative B&B depth limit. The "order" of a MIP problem is defined to be 2x the number of binary variables plus the number of SC and SOS variables. A relative value of -x results in a maximum depth of x times the order of the MIP problem. Remarks The set_bb_depthlimit function sets the maximum branch-and-bound depth. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_bb_depthlimit |
set_presolveSpecifies if a presolve must be done before solving. void set_presolve(lprec *lp, int do_presolve, int maxloops); Return Value set_presolve has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI do_presolve Specifies presolve level. Can be the (OR) combination of any of the following values:
maxloops The maximum number of times presolve may be done. Use get_presolveloops if you don't want to change this value. Remarks The set_presolve function specifies if a presolve must be done before
solving. Presolve looks at the model and tries to simplify it so that solving
times are shorter. For example a constraint on only one variable is converted
to a bound on this variable (and the constraint is deleted). Note that the
model dimensions can change because of this, so be careful with this. Both rows
and columns can be deleted by the presolve. int Norig_columns, Norig_rows, i; REAL value; Norig_columns = get_Norig_columns(lp); Norig_rows = get_Norig_rows(lp); for(i = 1; i <= Norig_columns; i++) { value = get_var_primalresult(lp, Norig_rows + i); printf("%f\n", value); } Note that there is no possibility to get the values of deleted rows. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_presolve, get_presolveloops, is_presolve |
get_epselReturns the value that is used as a tolerance for rounding values to zero. REAL get_epsel(lprec *lp); Return Value get_epsel returns the value of epsel. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The get_epsel function returns the value that is used for rounding values
to zero. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_epsel, set_infinite, get_infinite, is_infinite, set_epsint, get_epsint, set_epsd, get_epsd, set_epsb, get_epsb, get_epspivot, set_epspivot, set_epsperturb, get_epsperturb, set_mip_gap, get_mip_gap |
get_constraints, get_ptr_constraintsReturns the values of the constraints. unsigned char get_constraints(lprec *lp, REAL *constr); unsigned char get_ptr_constraints(lprec *lp, REAL **ptr_constr); Return Value get_constraints, get_ptr_constraints returns TRUE (1) if the operation
was successful. A return value of FALSE (0) indicates an error. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI constr An array that will contain the values of the constraints. ptr_constr The address of a pointer that will point to an array that will contain the values of the constraints. Remarks The get_constraints, get_ptr_constraints functions retrieve the
values of the constraints. Note that get_ptr_constraints returns a pointer to memory allocated and maintained by lp_solve. Be careful what you do with it. Don't modify its contents or free the memory. Unexpected behaviour would occur. Also note that this memory pointer is only guaranteed to remain constant until a next lp_solve API call is done. You should call this function again to make sure you have again the correct pointer. Otherwise, this pointer could point to invalid memory. This should not be a problem since this call is very efficient. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, is_feasible, get_objective, get_working_objective, get_variables, get_ptr_variables, get_primal_solution, get_ptr_primal_solution, get_var_primalresult, get_constr_value, get_sensitivity_rhs, get_ptr_sensitivity_rhs, get_dual_solution, get_ptr_dual_solution, get_var_dualresult, get_sensitivity_obj, get_ptr_sensitivity_obj, get_sensitivity_objex, get_ptr_sensitivity_objex, |
is_binaryGets the type of the variable. Binary integer or floating point. unsigned char is_binary(lprec *lp, int column); Return Value is_binary returns TRUE (1) if the variable is set as binary, FALSE (0)
otherwise. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI column The column number of the variable that must be checked. It must be between 1 and the number of columns in the lp. Remarks The is_binary function returns if a variable must be binary or not. Default a variable is not binary. A binary variable is an integer variable with lower bound 0 and upper bound 1. From the moment there is at least one integer variable in the model, the Branch and Bound algorithm is used to make these variables integer. Note that solving times can be considerably larger when there are integer variables. See integer variables for a description about integer variables. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_binary, is_int, set_int |
is_SOS_varReturns if the variable is SOS (Special Ordered Set) or not. unsigned char is_SOS_var(lprec *lp, int column); Return Value is_SOS_var returns TRUE (1) if the variable is a SOS var, FALSE (0) if
not. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI column The column number of the variable that must be checked. It must be between 1 and the number of columns in the lp. Remarks The is_SOS_var function returns if a variable is a SOS variable or not. Default a variable is not SOS. A variable becomes a SOS variable via add_SOS. See Special Ordered Sets for a description about SOS variables. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, add_SOS |
set_bb_ruleSpecifies the branch-and-bound rule. void set_bb_rule(lprec *lp, int bb_rule); Return Value set_bb_rule has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI bb_rule The branch-and-bound rule. Can by any of the following values:
One of these values may be or-ed with one or more of the following values:
Remarks The set_bb_rule function specifies the branch-and-bound rule for choosing
which non-integer variable is to be selected. This rule can influence solving
times considerably. Depending on the model one rule can be best and for another
model another rule. Example
See Also make_lp, copy_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_bb_rule, put_bb_nodefunc |
get_total_iterReturns the total number of iterations. long long get_total_iter(lprec *lp); Return Value get_total_iter returns the total number of iterations. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks If the model contains integer variables then it returns the number of iterations
to find a relaxed solution plus the number of iterations in the B&B process. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_max_level, get_total_nodes |
get_lp_indexReturns the index in the lp of the original row/column. int get_lp_index(lprec *lp, int orig_index); Return Value get_lp_index returns the index in the lp of the original row/column. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI orig_index Original constraint or column number. If orig_index is between 1 and get_Norig_rows then the index is a constraint (row) number. If orig_index is between 1+get_Norig_rows and get_Norig_rows + get_Norig_columns then the index is a column number. Remarks The get_lp_index function returns the index in the lp of the original row/column. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_orig_index, get_Ncolumns, get_Norig_columns, get_Nrows, get_Norig_rows, get_Lrows, set_presolve |
set_epsintSpecifies the tolerance that is used to determine whether a floating-point number is in fact an integer. void set_epsint(lprec *lp, REAL epsint); Return Value set_epsint has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI epsint The tolerance that is used to determine whether a floating-point number is in fact an integer. Remarks The set_epsint function specifies the tolerance that is used to determine
whether a floating-point number is in fact an integer. This is only used when
there is at least one integer variable and the branch and bound algorithm is
used to make variables integer. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_epsint, set_infinite, is_infinite, get_infinite, set_epsb, get_epsb, set_epsd, get_epsd, set_epsel, get_epsel, get_epspivot, set_epspivot, set_epsperturb, get_epsperturb, set_mip_gap, get_mip_gap |
get_maxpivotReturns the maximum number of pivots between a re-inversion of the matrix. int get_maxpivot(lprec *lp); Return Value get_maxpivot returns the maximum number of pivots between a
re-inversion of the matrix. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The get_maxpivot function returns the maximum number of pivots between
a re-inversion of the matrix. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_maxpivot |
Changes from version 5.1 to version 5.5Main features and changes to v5.5 compared to v5.1Why a jump from version numbers 5.1 to 5.5 ? This is done to indicate that this is more than just another update. The solver engine was revised and optimised in such a way that performance has improved considerably. Numerical stability is also better resulting in more models that can be solved. The LUSOL bfp is now also the default. In the past, the etaPFI bfp package was the default, but for larger models this leads faster to numerical instabilities and performance problems. Overall, the v5.5 code is faster and more robust than v5.1. This robustness is for example proven by the fact that many more models can now be solved even without scaling. The API hasn't changed very much. There are a couple of new routines and one routine has an extra argument. Some constants got new values.
Note the store and read options from a file. This can be a very nice new feature. lp_solve has a lot of options and with this new addition it is much easier to set these options. People can start looking for the best options that work for their models very easily and it could help to find even better default options. Changed API calls
New API calls
Removed API calls
|
set_upboSet the upper bound of a variable. unsigned char set_upbo(lprec *lp, int column, REAL value); Return Value set_upbo returns TRUE (1) if the operation was successful. A return value
of FALSE (0) indicates an error. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI column The column number of the variable on which the bound must be set. It must be between 1 and the number of columns in the lp. Remarks The set_upbo function sets an upper bound on the variable identified by column. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_upbo, set_lowbo, get_lowbo, set_bounds, set_unbounded, is_unbounded, is_negative |
integer variablesInteger variables are variables that must take an integer value (0, 1, 2, ...). A special kind of integer variables is binary variables. Binary variables can only take the value 0 or 1. They are integer variables with a maximum of 1 on them (and don't forget there is always an implicit minimum of 0 on each variable). If all variables are integer then it is a pure integer model, else it is a mixed-integer model, sometimes denoted as MIP (Mixed Integer Programming). There are many practical uses of such variables. Binary variables for example are used to specify that something may be used or not. Integer variables say that a variable must take a multiple of a given value. For example if you want that a given variable must be a multiple of 25 then you can construct following equation: var - 25 i = 0 with i the integer variable and var the variable that must be a multiple of 25. So an extra variable and an extra constraint is needed. This is ok if only a limited number of such variables are in the model, but if there are alot then the model dimensions will increase considerably. As an alternative you can also do a substitution of the variable: var = 25 i Everywhere where variable var is used, substitute it by 25 i. This in the objective function, the constraints and bounds. So variable var is removed from the model and replaced by i. i can be defined as integer. The objective value of this substituted model will be the same as the original one. However to obtain the value of variable var, you must multiply the returned variable i with 25. There is however one drawback on integer variables. These models are harder to solve and solution time can increment exponentially. The more integer variables there are the more time it takes to solve the model. A model without the integer variables may for example be solved in 0.1 seconds while the same model with some of the variables integer can take several minutes to solve. Be aware of this. Also try to limit the solution as much as possible. If you know some extra bounds on variables then it can be very good for the solution time to set them because this limits the number of combinations the algorithm has to examine. Another negative site on integer variables is the inaccurate sensitivity analysis when integer variables are used. See Inaccurate sensitivity analysis in a model with integer variables The integer solution is searched via the so-called 'branch-and-bound' algorithm. The model is first solved without the integer restrictions. Then it is investigated which of the integer variables are non-integer. When such a variable is found the model is split in two sub models. A first one with a minimum restriction on this variable that has the ceiling integer value and a second one with a maximum restriction on this variable that has the floor integer value. Both these sub models are optimised again and now this variable will have an integer value (if there is a solution). The algorithm then looks again if there are still (other) integer variables that have a non-integer value and if so the process is done again. This until a solution is found where are integer variables have integer values. This solution is then remembered as the best-until-now solution and the algorithm continues until it finds again an integer solution and if it is better it takes this one as the best-until-now solution. The more integer variables there are, the more combinations must be investigated and the more time it takes to solve the model. lp_solve supports integer variables since a long time. The API call set_int can be used to define a variable as integer. The API call set_binary can be used to define a variable as binary. In the mps format, integer variables can be specified in the
COLUMNS section. See mps-format .
ROWS N r_0 L r_1 G r_2 G r_3 G r_4 COLUMNS x1 r_0 -1 r_1 1 x1 r_2 2 r_3 -1 x2 r_0 -2 r_1 1 x2 r_2 -1 r_3 3 MARK0000 'MARKER' 'INTORG' x3 r_0 0.1 r_4 1 MARK0001 'MARKER' 'INTEND' x4 r_0 3 r_4 1 RHS RHS r_1 5 r_4 0.5 BOUNDS LO BND x3 1.1 ENDATA The red lines are two lines that specify that variable x3 is an integer variable. It also has a lower bound of 1.1 set on it. The solution of this model is: Value of objective function: -8.13333 Actual values of the variables: x1 1.66667 x2 3.33333 x3 2 x4 0 As can be seen, the value of x3 is 2, an integer value. If the integer restrictions would not be set on x3 then the value would be 1.1. In the lp-format, variables can be specified as integer by putting them in the int section. See lp-format. The above mps example would be in lp-format: 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; In the lp-format, variables can be specified as binary by putting them in the bin section. See lp-format. For example: 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; bin x3; |
R is a language and environment for statistical computing and graphics. It is a GNU project which is similar to the S language and environment which was developed at Bell Laboratories (formerly AT&T, now Lucent Technologies) by John Chambers and colleagues. R can be considered as a different implementation of S. There are some important differences, but much code written for S runs unaltered under R.
R provides a wide variety of statistical (linear and nonlinear modelling, classical statistical tests, time-series analysis, classification, clustering, ...) and graphical techniques, and is highly extensible. The S language is often the vehicle of choice for research in statistical methodology, and R provides an Open Source route to participation in that activity.
One of R's strengths is the ease with which well-designed publication-quality plots can be produced, including mathematical symbols and formulae where needed. Great care has been taken over the defaults for the minor design choices in graphics, but the user retains full control.
R is available as Free Software under the terms of the Free Software Foundation's GNU General Public License in source code form. It compiles and runs on a wide variety of UNIX platforms and similar systems (including FreeBSD and Linux), Windows and MacOS.
R is an integrated suite of software facilities for data manipulation, calculation and graphical display. It includes
The term "environment" is intended to characterize it as a fully planned and coherent system, rather than an incremental accretion of very specific and inflexible tools, as is frequently the case with other data analysis software.
R, like S, is designed around a true computer language, and it allows users to add additional functionality by defining new functions. Much of the system is itself written in the R dialect of S, which makes it easy for users to follow the algorithmic choices made. For computationally-intensive tasks, C, C++ and Fortran code can be linked and called at run time. Advanced users can write C code to manipulate R objects directly.
Many users think of R as a statistics system. We prefer to think of it of an environment within which statistical techniques are implemented. R can be extended (easily) via packages. There are about eight packages supplied with the R distribution and many more are available through the CRAN family of Internet sites covering a very wide range of modern statistics.
We will not discuss the specifics of R here but instead refer the reader to the R website. Also see An Introduction to R
lpsolve is callable from R via an extension or module. As such, it looks like lpsolve is fully integrated with R. Matrices can directly be transferred between R and lpsolve in both directions. The complete interface is written in C so it has maximum performance.
There are currently two R packages based on lp_solve. Both packages are available from CRAN.
The lpSolve R package is the first implementation of an interface of lpsolve to R.
It provides high-level functions for solving general linear/integer problems, assignment problems and transportation problems.
The following link contains the version of the driver: lpSolve: Interface to Lp_solve v. 5.5 to solve linear/integer programs.
It does not contain the lpsolve API. Only the higher level calls.
Documentation for this interface can be found on: Interface to Lp_solve v. 5.5 to solve linear/integer programs
This driver is written and maintained by Sam Buttrey.
The lpSolveAPI R package is a second implementation of an interface of lpsolve to R.
It provides an R API mirroring the lp_solve C API and hence provides a great deal more functionality but has a steeper learning curve.
The R interface to lpsolve contains its own documentation.
See An R interface to the lp_solve library for the driver.
This driver is written and maintained by Kjell Konis.
How to install the driver depends on the environment.
In the RGui menu, there is a menu item 'Packages'. From there a package can be installed from a CRAN mirror or from a local zip file.
Packages can also be installed from the R command line. This is a more general approach that will work under all environments.
Installing the package takes a single command:
The lpSolve R package:
> install.packages("lpSolve")and to install the lpSolveAPI package use the command:
> install.packages("lpSolveAPI")
The > shown before each R command is the R prompt. Only the text after > must be entered.
> library(lpSolveAPI)Or
> library("lpSolveAPI", character.only=TRUE)
Documentation is provided for each function in the lpSolve package using R's built-in help system. For example, the command
> ?add.constraintwill display the documentation for the add.constraint function.
This implementation provides the functions lp, lp.assign, lp.object, lp.transport and print.lp. These functions allow a linear program (and transport and assignment problems) to be defined and solved using a single command.
For more information enter:
> ?lp
> ?lp.assign
> ?lp.object
> ?lp.transport
> ?print.lp
See also Interface to Lp_solve v. 5.5 to solve linear/integer programs
This implementation provides an API for building and solving linear programs that mimics the lp_solve C API. This approach allows much greater flexibility but also has a few caveats. The most important is that the lpSolve linear program model objects created by make.lp and read.lp are not actually R objects but external pointers to lp_solve 'lprec' structures. R does not know how to deal with these structures. In particular, R cannot duplicate them. Thus one must never assign an existing lpSolve linear program model object in R code.
To load the library, enter:
> library(lpSolveAPI)
Consider the following example. First we create an empty model x.
> x <- make.lp(2, 2)Then we assign x to y.
> y <- xNext we set some columns in x.
> set.column(x, 1, c(1, 2)) > set.column(x, 2, c(3, 4))
And finally, take a look at y.
> y Model name: C1 C2 Minimize 0 0 R1 1 3 free 0 R2 2 4 free 0 Type Real Real upbo Inf Inf lowbo 0 0The changes we made in x appear in y as well. Although x and y are two distinct objects in R, they both refer to the same lp_solve 'lprec' structure.
The safest way to use the lpSolve API is inside an R function - do not return the lpSolve linear program model object.
> lprec <- make.lp(0, 4) > set.objfn(lprec, c(1, 3, 6.24, 0.1)) > add.constraint(lprec, c(0, 78.26, 0, 2.9), ">=", 92.3) > add.constraint(lprec, c(0.24, 0, 11.31, 0), "<=", 14.8) > add.constraint(lprec, c(12.68, 0, 0.08, 0.9), ">=", 4) > set.bounds(lprec, lower = c(28.6, 18), columns = c(1, 4)) > set.bounds(lprec, upper = 48.98, columns = 4) > RowNames <- c("THISROW", "THATROW", "LASTROW") > ColNames <- c("COLONE", "COLTWO", "COLTHREE", "COLFOUR") > dimnames(lprec) <- list(RowNames, ColNames)Lets take a look at what we have done so far.
> lprec # or equivalently print(lprec) Model name: COLONE COLTWO COLTHREE COLFOUR Minimize 1 3 6.24 0.1 THISROW 0 78.26 0 2.9 >= 92.3 THATROW 0.24 0 11.31 0 <= 14.8 LASTROW 12.68 0 0.08 0.9 >= 4 Type Real Real Real Real upbo Inf Inf Inf 48.98 lowbo 28.6 0 0 18Now lets solve the model.
> solve(lprec) [1] 0 > get.objective(lprec) [1] 31.78276 > get.variables(lprec) [1] 28.60000 0.00000 0.00000 31.82759 > get.constraints(lprec) [1] 92.3000 6.8640 391.2928
Note that there are some commands that return an answer. For the accessor functions (generally named get.*) the output should be clear. For other functions (e.g., solve), the interpretation of the returned value is described in the documentation. Since solve is generic in R, use the command
> ?solve.lpExtPtrto view the appropriate documentation. The assignment functions (generally named set.*) also have a return value - often a logical value indicating whether the command was successful - that is returned invisibly. Invisible values can be assigned but are not echoed to the console. For example,
> status <- add.constraint(lprec, c(12.68, 0, 0.08, 0.9), ">=", 4) > status [1] TRUEindicates that the operation was successful. Invisible values can also be used in flow control.
To free up resources and memory, the R command rm() must be used.
For example:
> rm(lprec)
See also Using lpsolve from MATLAB, Using lpsolve from O-Matrix, Using lpsolve from Octave, Using lpsolve from Python, Using lpsolve from Scilab
docs/5.5/is_presolve.htm 0000644 0001750 0001750 00000016421 11306036626 014034 0 ustar rene rene
is_presolveReturns if presolve level specified in testmask is active. unsigned char is_presolve(lprec *lp, int testmask); Return Value is_presolve returns TRUE or FALSE. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI testmask
Remarks The is_presolve function returns a flag if the presolve level specified
in testmask is active. Presolve looks at the model and tries to simplify
it so that solving times are shorter. For example a constraint on only one
variable is converted to a bound on this variable (and the constraint is
deleted). Note that the model dimensions can change because of this, so be
careful with this. Both rows and columns can be deleted by the presolve. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_presolve, get_presolve, get_presolveloops |
set_negrangeSet negative value below which variables are split into a negative and a positive part. void set_negrange(lprec *lp, REAL negrange); Return Value set_negrange has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI negrange The negative value below which variables are split into a negative and a positive part. RemarksThe set_negrange function specifies the negative value below which
variables are split into a negative and a positive part. This value must always
be zero or negative. If a positive value is specified, then 0 is taken. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_negrange |
set_epsperturbSpecifies the value that is used as perturbation scalar for degenerative problems. void set_epsperturb(lprec *lp, REAL epsperturb); Return Value set_epsperturb has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI epsperturb perturbation scalar. Remarks The default epsperturb value is 1e-5 Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_epsperturb, set_infinite, get_infinite, is_infinite, set_epsint, get_epsint, set_epsd, get_epsd, set_epsel, get_epsel, get_epspivot, set_epspivot, set_mip_gap, get_mip_gap |
set_basisSets an initial basis of the lp. unsigned char set_basis(lprec *lp, int *bascolumn, unsigned char nonbasic); Return Value set_basis returns TRUE if provided basis was set. FALSE if not. If FALSE then provided data was invalid. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI bascolumn An array with 1+get_Nrows or 1+get_Nrows+get_Ncolumns elements that specifies the basis. nonbasic If FALSE, then bascolumn must have 1+get_Nrows elements and only contains the basic variables. If TRUE, then bascolumn must have 1+get_Nrows+get_Ncolumns elements and will also contain the non-basic variables. Remarks
The set_basis function sets an initial basis of the lp. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_basis, default_basis, read_basis, write_basis, guess_basis, get_basiscrash, set_basiscrash |
read_paramsRead settings from a parameter file. unsigned char read_params(lprec *lp, char *filename, char *options); Return Value Returns TRUE (1) if parameters could be read, else FALSE (0). Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI filename Filename to read the parameters from. options Optional options. Can be: Remarks lp_solve parameters (options) are read from a parameter file. This file has an ini-format as used by Windows applications. All parameters are read from a header. This is by default [Default]. The header can be specified in the options parameter. Other headers are ignored. Example parameter file: [Default] ; lp_solve version 5.5 settings anti_degen=ANTIDEGEN_FIXEDVARS + ANTIDEGEN_STALLING + ANTIDEGEN_INFEASIBLE basiscrash=CRASH_NONE improve=IMPROVE_DUALFEAS + IMPROVE_THETAGAP maxpivot=250 negrange=-1e+006 pivoting=PRICER_DEVEX + PRICE_ADAPTIVE presolve=PRESOLVE_NONE presolveloops=2147483647 scalelimit=5 scaling=SCALE_GEOMETRIC + SCALE_EQUILIBRATE + SCALE_INTEGERS simplextype=SIMPLEX_DUAL_PRIMAL bb_depthlimit=-50 bb_floorfirst=BRANCH_AUTOMATIC bb_rule=NODE_PSEUDONONINTSELECT + NODE_GREEDYMODE + NODE_DYNAMICMODE + NODE_RCOSTFIXING ;break_at_first=0 ;break_at_value=-1e+030 mip_gap_abs=1e-011 mip_gap_rel=1e-011 epsint=1e-007 epsb=1e-010 epsd=1e-009 epsel=1e-012 epsperturb=1e-005 epspivot=2e-007 infinite=1e+030 ;debug=0 ;obj_bound=1e+030 ;print_sol=0 ;timeout=0 ;trace=0 ;verbose=NORMAL Note that there are some options commented out (;). This is done because these options can not be used in general for all models or because they are debug/trace/print options. These options can be made active and will be read by read_params but note again that they are possible dangerous to be used in general (except for the debug/trace/print options). Note that there are two kind of entries:
Numercial values can be integer values like maxpivot or floating point values like epsel Options are a combination of constants as defined in the manual. Multiple options are added with +. For example option anti_degen. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, write_params, reset_params |
ZimplZimpl is a language to translate the mathematical model of a problem into a linear or (mixed-) integer mathematical program expressed in .lp or .mps file format which can be read and (hopefully) solved by a LP or MIP solver. See http://www.zib.de/koch/zimpl/ for the home page of this tool and examples. On the above page, a command line tool is provided to read a model written in the Zimpl language and it creates a CPLEX lp file.
lp_solve is able to read this generated CPLEX lp file via the xli_CPLEX XLI driver, but that would require an extra step. lp_solve -rxli xli_Zimpl chvatal_diet.zpl This gives as result: Value of objective function: 97 Actual values of the variables: x$Oatmeal 4 x$Chicken 0 x$Eggs 0 x$Milk 5 x$Pie 2 x$Pork 0 OptionsThe XLI accepts several options: -b Enable Bison (Lex parser) debugging output. -D name=value Sets the parameter name to the specified value. This is equivalent with having this line in the ZIMPL program: param name:=val. -f enable flex debugging output. -n cm|cn|cf name column make/name/full -O Try to reduce the generated LP by doing some presolve analysis. -s seed Positive seed number for the random number generator. -v[0-5] Set the verbosity level. 0 is quiet, 1 is default, 2 is verbose, 3 and 4 are chatter, and 5 is debug. -V show version info These options are the same as the stand-alone zimpl program. The lp_solve command line program can provide these parameters via the -rxliopt argument. lp_solve -rxli xli_Zimpl chvatal_diet.zpl -rxliopt "-v0 -O" Generating ZIMPL modelsThe XLI can also create a ZIMPL model, however it doesn't use the strength of the language. Constraints are written out line per line. But it can be a starter. For example: lp_solve model.lp -wxli xli_Zimpl model.zpl This gives as model.zpl: # Variable definitions var x >= 0; var y >= 0; # Objective function maximize obj: +143*x +60*y; # Constraints subto R1: +120*x +210*y <= 15000; subto R2: +110*x +30*y <= 4000; subto R3: +x +y <= 75; APIUse the lpsolve API call read_XLI to read a model and write_XLI to write a model. See also External Language Interfaces. IDEAlso from within the IDE, this XLI can be used. However, some entries must be added in LpSolveIDE.ini (in the folder where the IDE is installed). In the [XLI] section the following must be added: lib5=xli_ZIMPL And a new section for the ZIMPL XLI must also be added: [xli_ZIMPL] extension=.zpl language=ZIMPL Then make sure that the xli_ZIMPL.dll is available for the IDE. This must be done by placing this dll in the IDE folder or in the Windows system32 folder. Example modelschvatal_diet.zpl# $Id: chvatal_diet.zpl,v 1.2 2003/10/02 08:20:12 bzfkocht Exp $ # # From V. Chvatal: Linear Programming # Chapter 1, Page 3ff. # # A diet problem # set Food := { "Oatmeal", "Chicken", "Eggs", "Milk", "Pie", "Pork" }; set Nutrients := { "Energy", "Protein", "Calcium" }; set Attr := Nutrients + {"Servings", "Price"}; param needed[Nutrients] := <"Energy"> 2000, <"Protein"> 55, <"Calcium"> 800; param data[Food * Attr] := | "Servings", "Energy", "Protein", "Calcium", "Price" | |"Oatmeal" | 4 , 110 , 4 , 2 , 3 | |"Chicken" | 3 , 205 , 32 , 12 , 24 | |"Eggs" | 2 , 160 , 13 , 54 , 13 | |"Milk" | 8 , 160 , 8 , 284 , 9 | |"Pie" | 2 , 420 , 4 , 22 , 20 | |"Pork" | 2 , 260 , 14 , 80 , 19 |; # (kcal) (g) (mg) (cents) var x[<f> in Food] integer >= 0 <= data[f, "Servings"]; minimize cost: sum <f> in Food : data[f, "Price"] * x[f]; subto need : forall <n> in Nutrients do sum <f> in Food : data[f, n] * x[f] >= needed[n]; model.lp/* model.lp */ max: 143 x + 60 y; 120 x + 210 y <= 15000; 110 x + 30 y <= 4000; x + y <= 75; |
read_lp, read_LPCreate an lprec structure and read an lp model from file. lprec *read_lp(FILE *stream, int verbose, char *lp_name); lprec *read_LP(char *filename, int verbose, char *lp_name); Return Value
Returns a pointer to a new lprec structure. This must be provided to almost all
lp_solve functions. Parameters stream Pointer to FILE structure. filename Filename to read the lp model from. verbose The verbose level. Can be one of the following values: See also set_verbose and get_verbose. lp_name Initial name of the model. See also set_lp_name and get_lp_name. May be NULL if the model has no name. Remarks The read_lp and read_LP functions construct a new lprec structure and read the model from filename. read_lp needs a file pointer to an already opened file. read_LP accepts the name of the file. The latter function will generally be more convenient.
The model in the file must be in lp-format.
Example
See Also delete_lp, free_lp, make_lp, copy_lp, write_lp, write_LP, write_lpex, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, write_mps, write_freemps, write_MPS, write_freeMPS, MPS_writefileex |
set_basiscrashDetermines a starting base. void set_basiscrash(lprec *lp, int mode); Return Value None Parameters Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI mode Specifies which basis crash mode is used. Can by any of the following values:
Remarks The set_basiscrash function specifies which basis crash mode must be used. Default is CRASH_NONE. When no base crash is done (the default), the initial basis from which lp_solve starts to solve the model is the basis containing all slack or artificial variables that is automatically associates with each constraint. When base crash is enabled, a heuristic ``crash procedure'' is executed before the first simplex iteration to quickly choose a basis matrix that has fewer artificial variables. This procedure tends to reduce the number of iterations to optimality since a number of iterations are skipped. lp_solve starts iterating from this basis until optimality. Example
See Also make_lp, copy_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_basiscrash, default_basis, read_basis, write_basis, guess_basis, get_basis, set_basis |
is_nativeBFPReturns if the native (build-in) basis factorization package (BFP) is used, or an external package. unsigned char is_nativeBFP(lprec *lp); Return Value is_nativeBFP returns TRUE if the native (build-in) BFP is used, else FALSE. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The is_nativeBFP function checks if an external BFP is set or not. See Basis Factorization Packages for a complete description on BFPs. Example
See Also make_lp, copy_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, has_BFP, set_BFP |
get_matGet a single element from the matrix. REAL get_mat(lprec *lp, int row, int column); Return Value
get_mat returns the value of the element on row row, column column.
If no value was set for this element, the function returns 0. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI row Row number of the matrix. Must be between 0 and number of rows in the lp. Row 0 is objective function. column Column number of the matrix. Must be between 1 and number of columns in the lp. Remarks
This function is not efficient if many values are to be retrieved. Consider to use
get_row, get_rowex, get_column, get_columnex. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_row, get_rowex, get_column, get_columnex, set_column, set_columnex, set_mat, set_row, set_rowex |
get_NrowsReturns the number of rows (constraints) in the lp. int get_Nrows(lprec *lp); Return Value get_Nrows returns the number of rows (constraints) in the lp. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The get_Nrows function returns the number of rows (constraints) in the lp. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_Norig_rows, get_Lrows, get_Ncolumns, get_Norig_columns, get_orig_index, get_lp_index |
lp_solve Frequently Asked Questions
- Where can I find the latest version of lp_solve?
- Can I use lp_solve in commercial code?
- Please explain what this LGPL license exactly means. I don't understand it. lp_solve used as compiled library? Yes No ----------- lp_solve Yes | B1 | B2 | code was |-----|-----| modified? No | A | B3 | -----------
A: "Work that uses the library" - But how much does lp_solve costs me? lp_solve is totally free - gratis - if you follow the rules of the LGPL. You may of course ask money for code you have developed or added, but only for that part, and the openness provisions of the LGPL have to be respected. If you are not willing to respect this, then the only recourse is that you seek an agreement with the copyright holders of the appropriate parts of lp_solve. - How should lp_solve be cited when I use it? lpsolve citation data ---------------------- Description : Open source (Mixed-Integer) Linear Programming system Language : Multi-platform, pure ANSI C / POSIX source code, Lex/Yacc based parsing Official name : lp_solve (alternatively lpsolve) Release data : Version 5.1.0.0 dated 1 May 2004 Co-developers : Michel Berkelaar, Kjell Eikland, Peter Notebaert Licence terms : GNU LGPL (Lesser General Public Licence) Citation policy : General references as per LGPL Module specific references as specified thereinThis text is also in citations.txt
- What are the default bounds on variables?
- Is it possible to set negative bounds on variables?
- Is it possible to set a minus infinite lower bound on a variable?
- What is the layout of the lp/mps/CPLEX format?
- When I call the API call solve(), several messages are printed on screen. How can I
disable those messages?
- lp_solve fails to solve my model or it takes a very long time to solve my model.
What can I do?
- Can lp_solve handle non-linear equations?
- Can lp_solve handle ratios? Have you entered your model via Word? Then the problem will probably be that some characters have ascii codes that are not recognised by lp_solve. For example, Word changes the minus sign (-) to another character that also looks like a minus sign, but it is a bit longer. The ascii code of this character is different from the ascii code of the real minus sign and lp_solve has problem with it. However you see a - on screen. The solution is not to use Word to enter your lp-model. Notepad should be ok. Better is to use the LPSolve IDE.
- lp_solve prints the output on screen. Can I have the output also in a file?
- I have a constraint saying that x < 2, but lp_solve comes with a solution of 2, how comes?
- When I solve my model, I get a stack overflow error/core dump/protection error. What is wrong?
- Version 4 solves my models slower than version 3 did. What can I do?
- It takes a long time to build the model via the API interface. Especially
add_constraint, add_constraintex, str_add_constraint
seems to be slow. How can it be made faster?
- Can lp_solve give me the 'simplex tableau' of the model?
- Is there documentation about the API interface?
- What is the maximum number of rows/columns that lp_solve can handle?
- I use a programming language that is not listed as supported or for which there
are no examples. Can lp_solve be called from this language?
- The Windows examples don't work. I get an error running them. Some dll cannot be
found.
- Does lp_solve supports the mps free format?
- Does the lp_solve lp format support comments?
- I want to compile lp_solve myself, but I get link errors. Also what should I
do with lp.y, lex.l, lp_rlp.y, lp_rlp.l?
- I compile lp_solve myself, but I get link errors saying that main (or _main)
is already defined.
- I want to use the lpsolve dll, but when I compile my C/C++ program, I get link
errors. He doesn't find any of the lpsolve API routines. What am I doing wrong?
- lp.c and lex.c that are generated on my system are different from the
versions that can be found in the support folder in the files section. Are the
latest versions of these files on your site?
- When I start the lp_solve program, nothing
happens. I just get a blinking cursor. If I enter a command like lp1 = make_lp(0,4),
I get a parse error. What is wrong here? How do I use the program? ROWS N r_0 L C1 L r_2 COLUMNS MARK0000 'MARKER' 'INTORG' x1 r_0 1 C1 2 x1 r_2 -4 x2 r_0 -2 C1 1 x2 r_2 4 MARK0001 'MARKER' 'INTEND' RHS RHS C1 5 r_2 5 ENDATA
To enable this input format in the lp_solve program, use the -mps option.
- Is there no more user-friendly interface than the lp_solve command line program? |
lag_solveSolve the model via Lagrangian relaxation. The Lagrangian solver does not work. Do not use this call. int lag_solve(lprec *lp, REAL start_bound, int num_iter, short verbose); Return Value
Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI start_bound Initial bound. num_iter Maximum number of iterations. verbose Not used. Still included for backwards compatibility. Use set_lag_trace to set the verbose level. Remarks The Lagrangian solver does not work. Do not use this call.
The lag_solve function solves the model via Lagrangian relaxation. Gives
the ability to find an integer solution without the branch-and-bound algorithm. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, solve, get_statustext, is_feasible, get_objective, get_working_objective, get_variables, get_ptr_variables, get_constraints, get_ptr_constraints, get_constr_value, get_sensitivity_rhs, get_ptr_sensitivity_rhs, get_dual_solution, get_ptr_dual_solution, get_var_dualresult, get_sensitivity_obj, get_ptr_sensitivity_obj, get_sensitivity_objex, get_ptr_sensitivity_objex, add_lag_con, get_Lrows |
set_maximSet objective function to maximize. void set_maxim(lprec *lp); Return Value set_maxim has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The set_maxim function sets the objective direction to maximize. The default of lp_solve is to minimize, except for read_lp, read_LP where the default is to maximize. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, is_maxim, set_minim, set_sense |
set_timeoutSet a timeout. void set_timeout(lprec *lp, long sectimeout); Return Value set_timeout has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI sectimeout The number of seconds after which a timeout occurs. If zero, then no timeout will occur. Remarks The set_timeout function sets a timeout in seconds. The solve
and lag_solve functions may not last longer than
this time or the routines return with a timeout. The default timeout is 0, resulting in no timeout. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_timeout, time_elapsed, solve, lag_solve |
DownloadAll needed files can be downloaded from sourceforge on the following location: https://sourceforge.net/project/showfiles.php?group_id=145213&package_id=159735 |
get_timeoutGets the timeout. long get_timeout(lprec *lp); Return Value get_timeout returns the number of seconds after which a timeout occurs. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The get_timeout function returns a timeout in seconds. The solve and lag_solve functions may not last longer than this time or the routines return with a timeout. There is no valid solution at this time. The default timeout is 0, resulting in no timeout. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_timeout, time_elapsed, solve, lag_solve |
put_bb_branchfuncSpecifies a user function to select a B&B branching, given the column to branch on. void put_bb_branchfunc(lprec *lp, lphandleint_intfunc newbranch, void *bb_branchhandle); Return Value put_bb_branchfunc has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI newbranch The branch routine. bb_branchhandle A parameter that will be provided to the branch routine. Remarks Specifies a user function to select a B&B branching, given the column to branch on. With this function you can specify which branch must be taken first in the B&B algorithm. The floor or the ceiling. This overrules the setting of set_bb_floorfirst. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_bb_floorfirst, get_bb_floorfirst, set_var_branch, get_var_branch, set_var_weights, get_var_priority |
GNU Octave is a high-level language, primarily intended for numerical computations. It provides a convenient command line interface for solving linear and non-linear problems numerically, and for performing other numerical experiments. It may also be used as a batch-oriented language.
GNU Octave is also freely redistributable software.
We will not discuss the specifics of Octave here but instead refer the reader to the Octave website and GNU Octave Repository.
lpsolve is callable from Octave via a dynamic linked function. As such, it looks like lpsolve is fully integrated with Octave. Matrices can directly be transferred between Octave and lpsolve in both directions. The complete interface is written in C so it has maximum performance. The whole lpsolve API is implemented with some extra's specific for Octave (especially for matrix support). So you have full control to the complete lpsolve functionality via the octlpsolve Octave driver. If you find that this involves too much work to solve an lp model then you can also work via higher-level script files that can make things a lot easier. See further in this article.
Note that your version of Octave must support dynamic linking. To find out if it does, type the command:
octave_config_info ("ENABLE_DYNAMIC_LINKING")
at the Octave prompt. Support for dynamic linking is included if this expression returns the string "true".
If this is not the case, then Octave is not able to call dynamic linked routines and as such also not lpsolve. In that case you must recompile Octave with dynamic linked routines enabled. Under Linux, the following commands must be executed for this:
configure --enable-shared make
See Installing Octave for more information.
Under Windows, dynamic linking should already be active. If not, then Octave must be recompiled. The following document can help in this process: README.Windows
The octave dynamic linked routine is in a file with extension .oct. It is impossible to provide a precompiled octlpsolve.oct file with the lpsolve distribution because the structure of the .oct files change often on new releases of Octave and are not compatible with each other. Therefore you must build the driver yourself. Look at the end of this document how to do this.
A driver program is needed: octlpsolve (octlpsolve.oct). This driver must be put in a directory known to Octave (in one of the directories from the Octave 'path' command) and Octave can call the octlpsolve solver.
This driver calls lpsolve via the lpsolve shared library (lpsolve55.dll under Windows and liblpsolve55.so under Unix/Linux) (in archives lp_solve_5.5.0.13_dev.zip/lp_solve_5.5.0.13_dev.tar.gz). This has the advantage that the octlpsolve driver doesn't have to be recompiled when an update of lpsolve is provided.
So note the difference between the Octave lpsolve driver that is called octlpsolve and the lpsolve library that implements the API that is called lpsolve55.
There are also some Octave script files (.m) as a quick start.
To test if everything is installed correctly, enter octlpsolve in the Octave command window. If it gives the following, then everything is ok:
octlpsolve Octave Interface version 5.5.0.5 using lpsolve version 5.5.0.13 Usage: [ret1, ret2, ...] = octlpsolve('functionname', arg1, arg2, ...)
However, if you get the following:
error: 'octlpsolve' undefined near line 2 column 1
Then Octave cannot find octlpsolve.oct
If you get the following:
error: Failed to initialise lpsolve library.
Then Octave can find the octlpsolve driver program, but the driver program cannot find the lpsolve library that contains the lpsolve implementation. This library is called lpsolve55.dll under Windows and liblpsolve55.so under Unix/Linux. Under Windows, the dll should be in a directory specified by the PATH environment variables and under Unix/Linux in directory /lib, /usr/lib or a directory defined by LD_LIBRARY_PATH.
In the following text, octave:> before the Octave commands is the Octave prompt. Only the text after octave:> must be entered. Note that the default prompt also contains an incrementing number starting from one each time Octave starts. For this documentation, the default Octave was changed with the following command: PS1 = "\\s:> "
To call an lpsolve function, the following syntax must be used:
octave:> [ret1, ret2, ...] = octlpsolve('functionname', arg1, arg2, ...)
The return values are optional and depend on the function called. functionname must always be enclosed between single or double quotes to make it alphanumerical and it is case sensitive. The number and type of arguments depend on the function called. Some functions even have a variable number of arguments and a different behaviour occurs depending on the type of the argument. functionname can be (almost) any of the lpsolve API routines (see lp_solve API reference) plus some extra Octave specific functions. Most of the lpsolve API routines use or return an lprec structure. To make things more robust in Octave, this structure is replaced by a handle or the model name. The lprec structures are maintained internally by the lpsolve driver. The handle is an incrementing number starting from 0. Starting from driver version 5.5.0.2, it is also possible to use the model name instead of the handle. This can of course only be done if a name is given to the model. This is done via lpsolve routine set_lp_name or by specifying the model name in routine read_lp. See Using model name instead of handle.
Almost all callable functions can be found in the lp_solve API reference. Some are exactly as described in the reference guide, others have a slightly different syntax to make maximum use of the Octave functionality. For example make_lp is used identical as described. But get_variables is slightly different. In the API reference, this function has two arguments. The first the lp handle and the second the resulting variables and this array must already be dimensioned. When lpsolve is used from Octave, nothing must be dimensioned in advance. The octlpsolve driver takes care of dimensioning all return variables and they are always returned as return value of the call to octlpsolve. Never as argument to the routine. This can be a single value as for get_objective (although Octave stores this in a 1x1 matrix) or a matrix or vector as in get_variables. In this case, get_variables returns a 4x1 matrix (vector) with the result of the 4 variables of the lp model.
Note that you can get an overview of the available functionnames and their arguments by entering the following in Octave:
>> help octlpsolve.m
(Note that you can execute this example by entering command per command as shown below or by just entering example1. This will execute example1.m. You can see its contents by entering type example1.m)
octave:> lp=octlpsolve('make_lp', 0, 4); octave:> octlpsolve('set_verbose', lp, 3); octave:> octlpsolve('set_obj_fn', lp, [1, 3, 6.24, 0.1]); octave:> octlpsolve('add_constraint', lp, [0, 78.26, 0, 2.9], 2, 92.3); octave:> octlpsolve('add_constraint', lp, [0.24, 0, 11.31, 0], 1, 14.8); octave:> octlpsolve('add_constraint', lp, [12.68, 0, 0.08, 0.9], 2, 4); octave:> octlpsolve('set_lowbo', lp, 1, 28.6); octave:> octlpsolve('set_lowbo', lp, 4, 18); octave:> octlpsolve('set_upbo', lp, 4, 48.98); octave:> octlpsolve('set_col_name', lp, 1, 'COLONE'); octave:> octlpsolve('set_col_name', lp, 2, 'COLTWO'); octave:> octlpsolve('set_col_name', lp, 3, 'COLTHREE'); octave:> octlpsolve('set_col_name', lp, 4, 'COLFOUR'); octave:> octlpsolve('set_row_name', lp, 1, 'THISROW'); octave:> octlpsolve('set_row_name', lp, 2, 'THATROW'); octave:> octlpsolve('set_row_name', lp, 3, 'LASTROW'); octave:> octlpsolve('write_lp', lp, 'a.lp'); octave:> octlpsolve('get_mat', lp, 1, 2) ans = 78.260 octave:> octlpsolve('solve', lp) ans = 0 octave:> octlpsolve('get_objective', lp) ans = 31.783 octave:> octlpsolve('get_variables', lp) ans = 28.60000 0.00000 0.00000 31.82759 octave:> octlpsolve('get_constraints', lp) ans = 92.3000 6.8640 391.2928
Note that there are some commands that return an answer. To see the answer, the command was not terminated with a semicolon (;). If the semicolon is put at the end of a command, the answer is not shown. However it is also possible to write the answer in a variable. For example:
octave:> obj=octlpsolve('get_objective', lp) obj = 31.783
Or without echoing on screen:
octave:> obj=octlpsolve('get_objective', lp);
The last command will only write the result in variable obj without showing anything on screen. get_variables and get_constraints return a vector with the result. This can also be put in a variable:
octave:> x=octlpsolve('get_variables', lp); octave:> b=octlpsolve('get_constraints', lp);
It is always possible to show the contents of a variable by just giving it as command:
octave:> x x = 28.60000 0.00000 0.00000 31.82759
Don't forget to free the handle and its associated memory when you are done:
octave:> octlpsolve('delete_lp', lp);
octave:> lp=octlpsolve('make_lp', 0, 4); octave:> octlpsolve('set_lp_name', lp, 'mymodel'); octave:> octlpsolve('set_verbose', 'mymodel', 3); octave:> octlpsolve('set_obj_fn', 'mymodel', [1, 3, 6.24, 0.1]); octave:> octlpsolve('add_constraint', 'mymodel', [0, 78.26, 0, 2.9], 2, 92.3); octave:> octlpsolve('add_constraint', 'mymodel', [0.24, 0, 11.31, 0], 1, 14.8); octave:> octlpsolve('add_constraint', 'mymodel', [12.68, 0, 0.08, 0.9], 2, 4); octave:> octlpsolve('set_lowbo', 'mymodel', 1, 28.6); octave:> octlpsolve('set_lowbo', 'mymodel', 4, 18); octave:> octlpsolve('set_upbo', 'mymodel', 4, 48.98); octave:> octlpsolve('set_col_name', 'mymodel', 1, 'COLONE'); octave:> octlpsolve('set_col_name', 'mymodel', 2, 'COLTWO'); octave:> octlpsolve('set_col_name', 'mymodel', 3, 'COLTHREE'); octave:> octlpsolve('set_col_name', 'mymodel', 4, 'COLFOUR'); octave:> octlpsolve('set_row_name', 'mymodel', 1, 'THISROW'); octave:> octlpsolve('set_row_name', 'mymodel', 2, 'THATROW'); octave:> octlpsolve('set_row_name', 'mymodel', 3, 'LASTROW'); octave:> octlpsolve('write_lp', 'mymodel', 'a.lp'); octave:> octlpsolve('get_mat', 'mymodel', 1, 2) ans = 78.260 octave:> octlpsolve('solve', 'mymodel') ans = 0 octave:> octlpsolve('get_objective', 'mymodel') ans = 31.783 octave:> octlpsolve('get_variables', 'mymodel') ans = 28.60000 0.00000 0.00000 31.82759 octave:> octlpsolve('get_constraints', 'mymodel') ans = 92.3000 6.8640 391.2928
So everywhere a handle is needed, you can also use the model name. You can even mix the two methods.
There is also a specific Octave routine to get the handle from the model name: get_handle.
For example:
>> octlpsolve('get_handle', 'mymodel') 0
Don't forget to free the handle and its associated memory when you are done:
octave:> octlpsolve('delete_lp', 'mymodel');
In the next part of this documentation, the handle is used. But if you name the model, the name could thus also be used.
octave:> octlpsolve('add_constraint', lp, [0.24, 0, 11.31, 0], 1, 14.8);
Most of the time, variables are used to provide the data:
octave:> octlpsolve('add_constraint', lp, a1, 1, 14.8);
Where a1 is a matrix variable.
Most of the time, octlpsolve needs vectors (rows or columns). In all situations, it doesn't matter if the vectors are row or column vectors. The driver accepts them both. For example:
octave:> octlpsolve('add_constraint', lp, [0.24; 0; 11.31; 0], 1, 14.8);
Which is a column vector, but it is also accepted.
An important final note. Several lp_solve API routines accept a vector where the first element (element 0) is not used. Other lp_solve API calls do use the first element. In the Octave interface, there is never an unused element in the matrices. So if the lp_solve API specifies that the first element is not used, then this element is not in the Octave matrix.
All numerical data is stored in matrices. Alphanumerical data, however, is more difficult to store in matrices. Matrices require that each element has the same size (length) and that is difficult and unpractical for alphanumerical data. In a limited number of lpsolve routines, alphanumerical data is required or returned and in some also multiple elements. An example is set_col_name. For this, Octave sets are used. To specify a set of alphanumerical elements, the following notation is used: { 'element1', 'element2', ... }. Note the { and } symbols instead of [ and ] that are used with matrices.
Because Octave is all about matrices, all lpsolve API routines that need a column or row number to get/set information for that
column/row are extended in the octlpsolve Octave driver to also work with matrices. For example set_int in the API can
only set the integer status for one column. If the status for several integer variables must be set, then set_int
must be called multiple times. The octlpsolve Octave driver however also allows specifying a vector to set the integer
status of all variables at once. The API call is: return = octlpsolve('set_int', lp, column, must_be_int). The
matrix version of this call is: return = octlpsolve('set_int', lp, [must_be_int]).
The API call to return the integer status of a variable is: return = octlpsolve('is_int', lp, column). The
matrix version of this call is: [is_int] = octlpsolve('is_int', lp)
Also note the get_mat and set_mat routines. In Octave these are extended to return/set the complete constraint matrix.
See following example.
Above example can thus also be done as follows:
(Note that you can execute this example by entering command per command as shown below or by just entering example2.
This will execute example2.m. You can see its contents by entering type example2.m)
octave:> lp=octlpsolve('make_lp', 0, 4); octave:> octlpsolve('set_verbose', lp, 3); octave:> octlpsolve('set_obj_fn', lp, [1, 3, 6.24, 0.1]); octave:> octlpsolve('add_constraint', lp, [0, 78.26, 0, 2.9], 2, 92.3); octave:> octlpsolve('add_constraint', lp, [0.24, 0, 11.31, 0], 1, 14.8); octave:> octlpsolve('add_constraint', lp, [12.68, 0, 0.08, 0.9], 2, 4); octave:> octlpsolve('set_lowbo', lp, [28.6, 0, 0, 18]); octave:> octlpsolve('set_upbo', lp, [Inf, Inf, Inf, 48.98]); octave:> octlpsolve('set_col_name', lp, {'COLONE', 'COLTWO', 'COLTHREE', 'COLFOUR'}); octave:> octlpsolve('set_row_name', lp, {'THISROW', 'THATROW', 'LASTROW'}); octave:> octlpsolve('write_lp', lp, 'a.lp'); octave:> octlpsolve('get_mat', lp) ans = 0.00000 78.26000 0.00000 2.90000 0.24000 0.00000 11.31000 0.00000 12.68000 0.00000 0.08000 0.90000 octave:> octlpsolve('solve', lp) ans = 0 octave:> octlpsolve('get_objective', lp) ans = 31.783 octave:> octlpsolve('get_variables', lp) ans = 28.60000 0.00000 0.00000 31.82759 octave:> octlpsolve('get_constraints', lp) ans = 92.3000 6.8640 391.2928
Note the usage of Inf in set_upbo. This stands for 'infinity'. Meaning an infinite upper bound. It is also possible to use -Inf to express minus infinity. This can for example be used to create a free variable.
To show the full power of the matrices, let's now do some matrix calculations to check the solution. It works further on above example:
octave:> A=octlpsolve('get_mat', lp); octave:> X=octlpsolve('get_variables', lp); octave:> B = A * X B = 92.3000 6.8640 391.2928
So what we have done here is calculate the values of the constraints (RHS) by multiplying the constraint matrix with the solution vector. Now take a look at the values of the constraints that lpsolve has found:
octave:> octlpsolve('get_constraints', lp) ans = 92.3000 6.8640 391.2928
Exactly the same as the calculated B vector, as expected.
Also the value of the objective can be calculated in a same way:
octave:> C=octlpsolve('get_obj_fn', lp); octave:> X=octlpsolve('get_variables', lp); octave:> obj = C * X obj = 31.783
So what we have done here is calculate the value of the objective by multiplying the objective vector with the solution vector. Now take a look at the value of the objective that lpsolve has found:
octave:> octlpsolve('get_objective', lp) ans = 31.783
Again exactly the same as the calculated obj value, as expected.
Octave can execute a sequence of statements stored in diskfiles. Script files mostly have the file type of ".m" as the last part of their filename (extension). Much of your work with Octave will be in creating and refining script files. Script files are usually created using your local editor.
Script files can be compared with batch files or scripts. You can put Octave commands in them and execute them at any time. The script file is executed like any other command, by entering its name (without the .m extension).
The octlpsolve Octave distribution contains some example script files to demonstrate this.
To see the contents of such a file, enter the command 'type filename'. You can also edit these files with your favourite text editor (or notepad).
Contains the commands as shown in the first example of this article.
Contains the commands as shown in the second example of this article.
Contains the commands of a practical example. See further in this article.
Contains the commands of a practical example. See further in this article.
Contains the commands of a practical example. See further in this article.
This script uses the API to create a higher-level function called lp_solve. This function accepts as arguments some matrices and options to create and solve an lp model. See the beginning of the file or type help lp_solve or just lp_solve to see its usage:
LP_SOLVE Solves mixed integer linear programming problems. SYNOPSIS: [obj,x,duals] = lp_solve(f,a,b,e,vlb,vub,xint,scalemode,keep) solves the MILP problem max v = f'*x a*x <> b vlb <= x <= vub x(int) are integer ARGUMENTS: The first four arguments are required: f: n vector of coefficients for a linear objective function. a: m by n matrix representing linear constraints. b: m vector of right sides for the inequality constraints. e: m vector that determines the sense of the inequalities: e(i) = -1 ==> Less Than e(i) = 0 ==> Equals e(i) = 1 ==> Greater Than vlb: n vector of lower bounds. If empty or omitted, then the lower bounds are set to zero. vub: n vector of upper bounds. May be omitted or empty. xint: vector of integer variables. May be omitted or empty. scalemode: scale flag. Off when 0 or omitted. keep: Flag for keeping the lp problem after it's been solved. If omitted, the lp will be deleted when solved. OUTPUT: A nonempty output is returned if a solution is found: obj: Optimal value of the objective function. x: Optimal value of the decision variables. duals: solution of the dual problem.
Example of usage. To create and solve following lp-model:
max: -x1 + 2 x2; C1: 2x1 + x2 < 5; -4 x1 + 4 x2 <5; int x2,x1;
The following command can be used:
octave:> [obj, x]=lp_solve([-1, 2], [2, 1; -4, 4], [5, 5], [-1, -1], [], [], [1, 2]) obj = 3 x = 1 2
This script is analog to the lp_solve script and also uses the API to create a higher-level function called lp_maker. This function accepts as arguments some matrices and options to create an lp model. Note that this scripts only creates a model and returns a handle. See the beginning of the file or type help lp_maker or just lp_maker to see its usage:
octave:> help lp_maker LP_MAKER Makes mixed integer linear programming problems. SYNOPSIS: lp_handle = lp_maker(f,a,b,e,vlb,vub,xint,scalemode,setminim) make the MILP problem max v = f'*x a*x <> b x >= vlb >= 0 x <= vub x(int) are integer ARGUMENTS: The first four arguments are required: f: n vector of coefficients for a linear objective function. a: m by n matrix representing linear constraints. b: m vector of right sides for the inequality constraints. e: m vector that determines the sense of the inequalities: e(i) < 0 ==> Less Than e(i) = 0 ==> Equals e(i) > 0 ==> Greater Than vlb: n vector of non-negative lower bounds. If empty or omitted, then the lower bounds are set to zero. vub: n vector of upper bounds. May be omitted or empty. xint: vector of integer variables. May be omitted or empty. scalemode: scale flag. Off when 0 or omitted. setminim: Set maximum lp when this flag equals 0 or omitted. OUTPUT: lp_handle is an integer handle to the lp created.
Example of usage. To create following lp-model:
max: -x1 + 2 x2; C1: 2x1 + x2 < 5; -4 x1 + 4 x2 <5; int x2,x1;
The following command can be used:
octave:> lp=lp_maker([-1, 2], [2, 1; -4, 4], [5, 5], [-1, -1], [], [], [1, 2]) lp = 0
To solve the model and get the solution:
octave:> octlpsolve('solve', lp) ans = 0 octave:> octlpsolve('get_objective', lp) ans = 3 octave:> octlpsolve('get_variables', lp) ans = 1 2
Don't forget to free the handle and its associated memory when you are done:
octave:> octlpsolve('delete_lp', lp);
Contains several examples to build and solve lp models.
Contains several examples to build and solve lp models. Also solves the lp_examples from the lp_solve distribution.
We shall illustrate the method of linear programming by means of a simple example, giving a combination graphical/numerical solution, and then solve both a slightly as well as a substantially more complicated problem.
Suppose a farmer has 75 acres on which to plant two crops: wheat and barley. To produce these crops, it costs the farmer (for seed, fertilizer, etc.) $120 per acre for the wheat and $210 per acre for the barley. The farmer has $15000 available for expenses. But after the harvest, the farmer must store the crops while awaiting favourable market conditions. The farmer has storage space for 4000 bushels. Each acre yields an average of 110 bushels of wheat or 30 bushels of barley. If the net profit per bushel of wheat (after all expenses have been subtracted) is $1.30 and for barley is $2.00, how should the farmer plant the 75 acres to maximize profit?
We begin by formulating the problem mathematically. First we express the objective, that is the profit, and the constraints algebraically, then we graph them, and lastly we arrive at the solution by graphical inspection and a minor arithmetic calculation.
Let x denote the number of acres allotted to wheat and y the number of acres allotted to barley. Then the expression to be maximized, that is the profit, is clearly
P = (110)(1.30)x + (30)(2.00)y = 143x + 60y.
There are three constraint inequalities, specified by the limits on expenses, storage and acreage. They are respectively:
120x + 210y <= 15000
110x + 30y <= 4000
x + y <= 75
Strictly speaking there are two more constraint inequalities forced by the fact that the farmer cannot plant a negative number of acres, namely:
x >= 0, y >= 0.
Next we graph the regions specified by the constraints. The last two say that we only need to consider the first quadrant in the x-y plane. Here's a graph delineating the triangular region in the first quadrant determined by the first inequality.
octave:> X = 0.1:0.1:125; octave:> Y1 = (15000 - 120.*X)./210; octave:> bar(X, Y1);
Now let's put in the other two constraint inequalities.
octave:> X = 0.1:0.05:40; octave:> Y1 = (15000. - 120*X)/210; octave:> Y2 = max((4000 - 110.*X)./30, 0); octave:> Y3 = max(75 - X, 0); octave:> Ytop = min([Y1; Y2; Y3]); octave:> bar(X, Ytop);
The red area is the solution space that holds valid solutions. This means that any point in this area fulfils the constraints.
Now let's superimpose on top of this picture the objective function P.
octave:> hold on octave:> X=15:25:40; octave:> title('Solution space and objective') octave:> plot(X,(6315.63-143.0*X)/60.0); octave:> hold off
The line gives a picture of the objective function. All solutions that intersect with the red area are valid solutions, meaning that this result also fulfils the set constraints. The more the line goes to the right, the higher the objective value is. The optimal solution or best objective is a line that is still in the red area, but with an as large as possible value.
It seems apparent that the maximum value of P will occur on the level curve (that is, level
line) that passes through the vertex of the polygon that lies near (22,53).
It is the intersection of x + y = 75 and 110*x + 30*y = 4000
This is a corner point of the diagram. This is not a coincidence. The simplex algorithm, which is used
by lp_solve, starts from a theorem that the optimal solution is such a corner point.
In fact we can compute the result:
octave:> x = [1 1; 110 30] \ [75; 4000] x = 21.875 53.125
The acreage that results in the maximum profit is 21.875 for wheat and 53.125 for barley. In that case the profit is:
octave:> P = [143 60] * x P = 6315.6
That is, $6315.6.
Note that these command are in script example3.m
Now, lp_solve comes into the picture to solve this linear programming problem more generally. After that we will use it to solve two more complicated problems involving more variables and constraints.
For this example, we use the higher-level script lp_maker to build the model and then some lp_solve API calls to retrieve the solution. Here is again the usage of lp_maker:
LP_MAKER Makes mixed integer linear programming problems. SYNOPSIS: lp_handle = lp_maker(f,a,b,e,vlb,vub,xint,scalemode,setminim) make the MILP problem max v = f'*x a*x <> b x >= vlb >= 0 x <= vub x(int) are integer ARGUMENTS: The first four arguments are required: f: n vector of coefficients for a linear objective function. a: m by n matrix representing linear constraints. b: m vector of right sides for the inequality constraints. e: m vector that determines the sense of the inequalities: e(i) < 0 ==> Less Than e(i) = 0 ==> Equals e(i) > 0 ==> Greater Than vlb: n vector of non-negative lower bounds. If empty or omitted, then the lower bounds are set to zero. vub: n vector of upper bounds. May be omitted or empty. xint: vector of integer variables. May be omitted or empty. scalemode: scale flag. Off when 0 or omitted. setminim: Set maximum lp when this flag equals 0 or omitted. OUTPUT: lp_handle is an integer handle to the lp created.
Now let's formulate this model with lp_solve:
octave:> f = [143 60]; octave:> A = [120 210; 110 30; 1 1]; octave:> b = [15000; 4000; 75]; octave:> lp = lp_maker(f, A, b, [-1; -1; -1], [], [], [], 1, 0); octave:> solvestat = octlpsolve('solve', lp) solvestat = 0 octave:> obj = octlpsolve('get_objective', lp) obj = 6315.6 octave:> x = octlpsolve('get_variables', lp) x = 21.875 53.125 octave:> octlpsolve('delete_lp', lp);
Note that these command are in script example4.m
With the higher-level script lp_maker, we provide all data to lp_solve. lp_solve returns a handle (lp) to the created model. Then the API call 'solve' is used to calculate the optimal solution of the model. The value of the objective function is retrieved via the API call 'get_objective' and the values of the variables are retrieved via the API call 'get_variables'. At last, the model is removed from memory via a call to 'delete_lp'. Don't forget this to free all memory allocated by lp_solve.
The solution is the same answer we obtained before. Note that the non-negativity constraints are accounted implicitly because variables are by default non-negative in lp_solve.
Well, we could have done this problem by hand (as shown in the introduction) because it is very small and it
can be graphically presented.
Now suppose that the farmer is dealing with a third crop, say corn, and that the corresponding data is:
cost per acre $150.75 yield per acre 125 bushels profit per bushel $1.56
With three variables it is already a lot more difficult to show this model graphically. Adding more variables makes it even impossible because we can't imagine anymore how to represent this. We only have a practical understanding of 3 dimentions, but beyound that it is all very theorethical.
If we denote the number of acres allotted to corn by z, then the objective function becomes:
P = (110)(1.30)x + (30)(2.00)y + (125)(1.56) = 143x + 60y + 195z
And the constraint inequalities are:
120x + 210y + 150.75z <= 15000
110x + 30y + 125z <= 4000
x + y + z <= 75
x >= 0, y >= 0, z >= 0
The problem is solved with lp_solve as follows:
octave:> f = [143 60 195]; octave:> A = [120 210 150.75; 110 30 125; 1 1 1]; octave:> b = [15000; 4000; 75]; octave:> lp = lp_maker(f, A, b, [-1; -1; -1], [], [], [], 1, 0); octave:> solvestat = octlpsolve('solve', lp) solvestat = 0 octave:> obj = octlpsolve('get_objective', lp) obj = 6986.8 octave:> x = octlpsolve('get_variables', lp) x = 0.00000 56.57895 18.42105 octave:> octlpsolve('delete_lp', lp);
Note that these command are in script example5.m
So the farmer should ditch the wheat and plant 56.5789 acres of barley and 18.4211 acres of corn.
There is no practical limit on the number of variables and constraints that Octave can handle. Certainly none that the relatively unsophisticated user will encounter. Indeed, in many true applications of the technique of linear programming, one needs to deal with many variables and constraints. The solution of such a problem by hand is not feasible, and software like Octave is crucial to success. For example, in the farming problem with which we have been working, one could have more crops than two or three. Think agribusiness instead of family farmer. And one could have constraints that arise from other things beside expenses, storage and acreage limitations. For example:
Below is a sequence of commands that solves exactly such a problem. You should be able to recognize the objective expression and the constraints from the data that is entered. But as an aid, you might answer the following questions:
octave:> f = [110*1.3 30*2.0 125*1.56 75*1.8 95*.95 100*2.25 50*1.35]; octave:> A = [120 210 150.75 115 186 140 85; 110 30 125 75 95 100 50; 1 1 1 1 1 1 1; 1 -1 0 0 0 0 0; 0 0 1 0 -2 0 0; 0 0 0 -1 0 -1 1]; octave:> b = [55000;40000;400;0;0;0]; octave:> lp = lp_maker(f, A, b, [-1; -1; -1; -1; -1; -1], [10 10 10 10 20 20 20], [100 Inf 50 Inf Inf 250 Inf], [], 1, 0); octave:> solvestat = octlpsolve('solve', lp) solvestat = 0 octave:> obj = octlpsolve('get_objective', lp) obj = 7.5398e+04 octave:> x = octlpsolve('get_variables', lp) x = 10.000 10.000 40.000 45.652 20.000 250.000 20.000 octave:> octlpsolve('delete_lp', lp);
Note that these command are in script example6.m
Note that we have used in this formulation the vlb and vub arguments of lp_maker. This to set lower and upper bounds on variables. This could have been done via extra constraints, but it is more performant to set bounds on variables. Also note that Inf is used for variables that have no upper limit. This stands for Infinity.
Note that despite the complexity of the problem, lp_solve solves it almost instantaneously. It seems the farmer should bet the farm on crop number 6. We strongly suggest you alter the expense and/or the storage limit in the problem and see what effect that has on the answer.
Suppose we want to solve the following linear program using Octave:
max 4x1 + 2x2 + x3
s. t. 2x1 + x2 <= 1
x1 + 2x3 <= 2
x1 + x2 + x3 = 1
x1 >= 0
x1 <= 1
x2 >= 0
x2 <= 1
x3 >= 0
x3 <= 2
Convert the LP into Octave format we get:
f = [4 2 1]
A = [2 1 0; 1 0 2; 1 1 1]
b = [1; 2; 1]
Note that constraints on single variables are not put in the constraint matrix. lp_solve can set bounds on individual variables and this is more performant than creating additional constraints. These bounds are:
l = [ 0 0 0]
u = [ 1 1 2]
Now lets enter this in Octave:
octave:> f = [4 2 1]; octave:> A = [2 1 0; 1 0 2; 1 1 1]; octave:> b = [1; 2; 1]; octave:> l = [ 0 0 0]; octave:> u = [ 1 1 2];
Now solve the linear program using Octave: Type the commands
octave:> lp = lp_maker(f, A, b, [-1; -1; -1], l, u, [], 1, 0); octave:> solvestat = octlpsolve('solve', lp) solvestat = 0 octave:> obj = octlpsolve('get_objective', lp) obj = 2.5000 octave:> x = octlpsolve('get_variables', lp) x = 0.50000 0.00000 0.50000 octave:> octlpsolve('delete_lp', lp)
What to do when some of the variables are missing ?
For example, suppose there are no lower bounds on the variables. In this case define l to be the empty set using the Octave command:
octave:> l = [];
This has the same effect as before, because lp_solve has as default lower bound for variables 0.
But what if you want that variables may also become negative?
Then you can use -Inf as lower bounds:
octave:> l = [-Inf -Inf -Inf];
Solve this and you get a different result:
octave:> lp = lp_maker(f, A, b, [-1; -1; -1], l, u, [], 1, 0); octave:> solvestat = octlpsolve('solve', lp) solvestat = 0 octave:> obj = octlpsolve('get_objective', lp) obj = 2.6667 octave:> x = octlpsolve('get_variables', lp) x = 0.66667 -0.33333 0.66667 octave:> octlpsolve('delete_lp', lp)
Note again that the Octave command 'help octlpsolve.m' gives an overview of all functions that can be called via octlpsolve with their arguments and return values.
Note that everwhere where lp is used as argument that this can be a handle (lp_handle) or the models name.
These routines are not part of the lpsolve API, but are added for backwards compatibility. Most of them exist in the lpsolve API with another name.
See also Using lpsolve from O-Matrix, Using lpsolve from MATLAB, Using lpsolve from Scilab, Using lpsolve from Python, Using lpsolve from R
docs/5.5/get_constr_type.htm 0000644 0001750 0001750 00000005745 11306036626 014721 0 ustar rene rene
get_constr_typeGets the type of a constraint. int get_constr_type(lprec *lp, int row); Return Value get_constr_type returns the type of the constraint on row row. Can by any of the following values:
If there is an error then the function returns -1. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI row The row for which the constraint type must be retrieved. Must be between 1 and number of rows in the lp. Remarks The get_constr_type function returns the constraint type for the
specified row. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, is_constr_type, set_constr_type, add_constraint, add_constraintex, str_add_constraint, del_constraint |
get_scalelimitSets the relative scaling convergence criterion for the active scaling mode. REAL get_scalelimit(lprec *lp); Return Value get_scalelimit returns the relative scaling convergence criterion for the active scaling mode; the integer part specifies the maximum number of iterations. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI scalelimit maximum number of iterations Remarks The get_scalelimit function the relative scaling convergence criterion for the active scaling mode; the integer part specifies the maximum number of iterations (default is 5). Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_scalelimit, set_scaling, get_scaling, is_integerscaling |
is_nativeXLIReturns if a build-in External Language Interfaces (XLI) is available or not. unsigned char is_nativeXLI(lprec *lp); Return Value is_nativeXLI returns TRUE if a build-in XLI is available, FALSE if not. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks At this moment, this routine always returns FALSE since no build-in XLI is available. See External Language Interfaces for a complete description on XLIs. Example
See Also make_lp, copy_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, write_XLI, has_XLI, set_XLI |
put_abortfuncSets an abort routine. void put_abortfunc(lprec *lp, lphandle_intfunc newctrlc, void *ctrlchandle); Return Value put_abortfunc has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI newctrlc The abort routine. ctrlchandle A parameter that will be provided to the abort routine. Remarks The put_abortfunc function sets an abort routine. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, put_logfunc |
set_print_solSets a flag if all intermediate valid solutions must be printed while solving. void set_print_sol(lprec *lp, int print_sol); Return Value set_print_sol has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI print_sol
Remarks The set_print_sol function sets a flag if all intermediate valid solutions must be printed while solving. Can give you useful solutions even if the total run time is too long. This function is mend for debugging purposes. The default is not to print (FALSE). Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_print_sol |
get_mip_gapReturns the MIP gap value. REAL get_mip_gap(lprec *lp, unsigned char absolute); Return Value get_mip_gap returns the MIP gap value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI absolute If TRUE then the absolute MIP gap is returned, else the relative MIP gap. Remarks The get_mip_gap function returns the MIP gap that specifies a tolerance
for the branch and bound algorithm. This tolerance is the difference between
the best-found solution yet and the current solution. If the difference is
smaller than this tolerance then the solution (and all the sub-solutions) is
rejected. This can result in faster solving times, but results in a solution
which is not the perfect solution. So be careful with this tolerance. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_mip_gap, get_epsd, set_epsd, set_infinite, get_infinite, set_epsint, get_epsint, set_epsb, get_epsb, set_epsel, get_epsel, get_epspivot, set_epspivot, set_epsperturb, get_epsperturb |
get_var_priorityReturns, for the specified variable, the priority the variable has in the branch-and-bound algorithm. int get_var_priority(lprec *lp, int column); Return Value get_var_priority returns the priority of the variable. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI column The column number of the variable on which the priority must be returned. It must be between 1 and the number of columns in the lp. If it is not within this range, the return value is 0 Remarks The get_var_priority function returns the priority the variable has in the branch-and-bound algorithm. This priority is determined by the weights set by set_var_weights. The default priorities are the column positions of the variables in the model. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_var_weights, get_var_branch, set_var_branch, set_bb_floorfirst, get_bb_floorfirst |
add_constraint, add_constraintex, str_add_constraintAdd a constraint to the lp. unsigned char add_constraint(lprec *lp, REAL *row, int constr_type, REAL rh); unsigned char add_constraintex(lprec *lp, int count, REAL *row, int *colno, int constr_type, REAL rh); unsigned char str_add_constraint(lprec *lp, char *row_string, int constr_type, REAL rh); Return Value add_constraint, add_constraintex and str_add_constraint return TRUE (1) if the operation was successful. A return value of FALSE (0) indicates an error. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI count Number of elements in row and colno. row An array with 1+get_Ncolumns (count for add_constraintex, if colno is different from NULL) elements that contains the values of the row. colno A zero-based array with count elements that contains the column numbers of the row. However this variable can also be NULL. In that case element i in the variable row is column i and values start at element 1. row_string A string with column elements that contains the values of the row. Each element must be separated by space(s). constr_type The type of the constraint. Can by any of the following values:
rh The value of the right hand side (RHS). Remarks The add_constraint, add_constraintex, str_add_constraint functions add a row to the
model (at the end) and sets all values of the row at once. Example
See Also make_lp, copy_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_row, set_rowex, set_obj_fn, set_obj_fnex, str_set_obj_fn, set_obj, set_add_rowmode, is_add_rowmode, resize_lp, get_constr_type, is_constr_type, del_constraint, add_column, add_columnex, str_add_column, set_column, set_columnex, get_column, get_columnex, get_row, get_rowex, get_mat |
set_scalingSpecifies which scaling algorithm must be used. void set_scaling(lprec *lp, int scalemode); Return Value set_scaling has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI scalemode Specifies which scaling algorithm must be used. Can by any of the
following values:
Additionally, the value can be OR-ed with any combination of one of the following values:
Remarks The set_scaling function specifies which scaling algorithm must be
used. This can influence numerical stability considerably. It is advisable to
always use some sort of scaling. Also see scaling for a description about scaling. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_scaling, is_integerscaling, is_scalemode, is_scaletype |
Special Ordered Sets (SOS)Special Ordered Sets of Type OneA Special Ordered Set of type One (SOS1) is defined to be a set of variables for which not more than one member from the set may be non-zero in a feasible solution. All such sets are mutually exclusive of each other, the members are not subject to any other discrete conditions and are grouped together consecutively in the data. The normal use of an SOS1 is to represent a set of mutually exclusive alternatives ordered in increasing values of size, cost or some other suitable units appropriate to the context of the model. This representation is a discrete programming extension of the separable programming model. There is a strong implied assumption that a non-linear function represented in this way is single valued over the range of its argument. Consider a function g(y) represented by the points P1,...,PK as shown in figure 2.
Figure 2
Given
the tabulated coordinates where The
discrete function can take only one of the This requirement could be expressed by restricting each xk to be a binary variable but the alternative of defining them collectively as a special ordered set of type one, which is a direct statement of their nature, leads to a more efficient solution process. The weighting variables xk are called special ordered set type one variables and the rows (1), (2), and (3) are called function rows, reference rows and convexity rows respectively. Should the SOS1's not represent a modelling of discrete, separable variables then none of these rows need actually exist, but there is an advantage to the system if it is aware of the reference rows at least.
Special Ordered Sets of Type TwoA Special Ordered Set of type Two (SOS2) is a set of consecutive variables in which not more than two adjacent members may be non-zero in a feasible solution. All such sets are mutually exclusive of each other, the members are not subject to any other discrete conditions and each set is grouped together consecutively in the data. SOS2s were introduced to make it easier to find global optimum solutions to problems containing piecewise linear approximations to a non-linear function of a single argument (as in classical Separable Programming). The overall problem has an otherwise LP or an IP structure except for such non-linear functions. Consider
the function
Figure 3
Any
point
where
Similarly,
as
This
leads to the representation of where Plus the added condition that not more than two adjacent variables can be non-zero at any one time. The weighting variables xk are called the special ordered set type two variables and the rows (4), (5), and (6) are called function rows, reference rows and the convexity rows respectively, as in equations (1), (2) and (3) of Topic "Special Ordered Sets of Type One". Should the SOS2's not represent separable functions then none of these rows need actually exist, but there is an advantage to the system if it is aware of the reference rows at least.
The lp_solve implementation of SOS is the following:A specially ordered set of degree N is a collection of variables where at most N variables may be non-zero. The non-zero variables must be contiguous (neighbours) sorted by the ascending value of their respective unique weights. In lp_solve, specially ordered sets may be of any cardinal type 1, 2, and higher, and may be overlapping. The number of variables in the set must be equal to, or exceed the cardinal SOS order. lp_solve supports Special Ordered Sets via the API interface, in the MPS format and in the lp format (from release 4.0.1.11). Below is a representation of a SOS in an MPS file, where each SOS is defined in its own SOS section, which should follow the BOUNDS section. 0 1 2 3 4 1234567890123456789012345678901234567890 SOS Sx CaseName SOSName. SOSpriority. CaseName VarName1 VarWeight1.. CaseName VarName2 VarWeight2.. CaseName VarNameN VarWeightN.. x at the second line, position 3, defines is the order of the SOS. Due to limitations in the MPS format, N is restricted to the 1..9 range. Each SOS should be given a unique name, SOSName. lp_solve does not currently use case names for SOS'es and the CaseName could be any non-empty value. Below is a representation of a SOS in an lp file. sos SOS: VarName1: VarWeight1, VarName2: VarWeight2, ..., VarNameN: VarWeightN <= 1: SOSpriority; In the lp format, the VarWeights are optional: sos SOS: VarName1, VarName2, ..., VarNameN <= 1: SOSpriority; In that case, the order of the variables define the VarWeights. So above is equal to: sos SOS: VarName1: 1, VarName2: 2, ..., VarNameN: N <= 1: SOSpriority; Also the SOSpriority is optional. In that case the order in which the SOS constraints are specified give them a priority. The SOSpriority value determines the order in which multiple SOS'es are analysed in lp_solve. VarWeight determines the adjacency of the variables. This is an importand piece of information. Remember that the SOS definition defines that the non-zero variables must be adjacent. The VarWeight values define this adjencency. SOS1 Example: ROWS L c1 L c2 N COST COLUMNS x1 c1 -1. c2 1. x1 COST -1. x2 c1 -1. COST -1. x3 c1 1. c2 1. x3 COST -3. x4 c1 1. c2 -3. x4 COST -2. x5 COST -2. RHS RHS c1 30. c2 30. BOUNDS UP COLBND x1 40. UP COLBND x2 1. UP COLBND x5 1. SOS S1 SOS SOS 1. SOS x1 1. SOS x2 2. SOS x3 3. SOS x4 4. SOS x5 5. ENDATA In lp format: 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 SOS: x1,x2,x3,x4,x5 <= 1; The SOS definition says that either x1 or x2 or x3 or x4 or x5 may be taken. It also says that x1 is adjacent to x2 which is adjacent to x3 which is adjacent to x4 which is adjacent to x5. The solution is:Value of objective function: -90 Actual values of the variables: x1 0 x2 0 x3 30 x4 0 x5 0 SOS2 Example: ROWS L c1 L c2 N COST COLUMNS x1 c1 -1. c2 1. x1 COST -1. x2 c1 -1. COST -1. x3 c1 1. c2 1. x3 COST -3. x4 c1 1. c2 -3. x4 COST -2. x5 COST -2. RHS RHS c1 30. c2 30. BOUNDS UP COLBND x1 40. UP COLBND x2 1. UP COLBND x5 1. SOS S2 SOS SOS 1. SOS x1 1. SOS x2 2. SOS x3 3. SOS x4 4. SOS x5 5. ENDATA In lp format: 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 SOS: x1,x2,x3,x4,x5 <= 2; The SOS definition says that two consecutive variables from x1, x2, x3, x4, x5 may be taken. It also says that x1 is adjacent to x2 which is adjacent to x3 which is adjacent to x4 which is adjacent to x5. The solution is:Value of objective function: -91 Actual values of the variables: x1 0 x2 1 x3 30 x4 0 x5 0 SOS3 Example: ROWS L c1 L c2 N COST COLUMNS x1 c1 -1. c2 1. x1 COST -1. x2 c1 -1. COST -1. x3 c1 1. c2 1. x3 COST -3. x4 c1 1. c2 -3. x4 COST -2. x5 COST -2. RHS RHS c1 30. c2 30. BOUNDS UP COLBND x1 40. UP COLBND x2 1. UP COLBND x5 1. SOS S3 SOS SOS 1. SOS x1 1. SOS x2 2. SOS x3 3. SOS x4 4. SOS x5 5. ENDATA In lp format: 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 SOS: x1,x2,x3,x4,x5 <= 3; The SOS definition says that three consecutive variables from x1, x2, x3, x4, x5 may be taken. It also says that x1 is adjacent to x2 which is adjacent to x3 which is adjacent to x4 which is adjacent to x5. The solution is:Value of objective function: -93.75 Actual values of the variables: x1 0 x2 1 x3 30.75 x4 0.25 x5 0 SOS4 Example: ROWS L c1 L c2 N COST COLUMNS x1 c1 -1. c2 1. x1 COST -1. x2 c1 -1. COST -1. x3 c1 1. c2 1. x3 COST -3. x4 c1 1. c2 -3. x4 COST -2. x5 COST -2. RHS RHS c1 30. c2 30. BOUNDS UP COLBND x1 40. UP COLBND x2 1. UP COLBND x5 1. SOS S4 SOS SOS 1. SOS x1 1. SOS x2 2. SOS x3 3. SOS x4 4. SOS x5 5. ENDATA In lp format: 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 SOS: x1,x2,x3,x4,x5 <= 4; The SOS definition says that four consecutive variables from x1, x2, x3, x4, x5 may be taken. It also says that x1 is adjacent to x2 which is adjacent to x3 which is adjacent to x4 which is adjacent to x5. The solution is:Value of objective function: -233.75 Actual values of the variables: x1 40 x2 1 x3 50.75 x4 20.25 x5 0 SOS5 Example: ROWS L c1 L c2 N COST COLUMNS x1 c1 -1. c2 1. x1 COST -1. x2 c1 -1. COST -1. x3 c1 1. c2 1. x3 COST -3. x4 c1 1. c2 -3. x4 COST -2. x5 COST -2. RHS RHS c1 30. c2 30. BOUNDS UP COLBND x1 40. UP COLBND x2 1. UP COLBND x5 1. SOS S5 SOS SOS 1. SOS x1 1. SOS x2 2. SOS x3 3. SOS x4 4. SOS x5 5. ENDATA In lp format: 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 SOS: x1,x2,x3,x4,x5 <= 5; The SOS definition says that five consecutive variables from x1, x2, x3, x4, x5 may be taken. It also says that x1 is adjacent to x2 which is adjacent to x3 which is adjacent to x4 which is adjacent to x5. The solution is:Value of objective function: -235.75 Actual values of the variables: x1 40 x2 1 x3 50.75 x4 20.25 x5 1 |
set_senseSet objective function sense. void set_sense(lprec *lp, unsigned char maximize); Return Value set_sense has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI maximize Set sense to minimize (FALSE) or maximize (TRUE). Remarks The set_sense function sets the objective sense. The default of lp_solve is to minimize, except for read_lp, read_LP where the default is to maximize. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_minim, set_maxim, is_maxim |
GNU MathProgGNU MathProg is a modeling language intended for describing linear mathematical programming models.
See http://gnuwin32.sourceforge.net/downlinks/glpk-doc-zip.php for a complete description of this modeling language. GNU MathProg is part of the GLPK solver.
See http://www.gnu.org/software/glpk/glpk.html
and http://gnuwin32.sourceforge.net/packages/glpk.htm
for the homepage of it. lp_solve -rxli xli_MathProg Diet1.mod This gives as result: Value of objective function: 88.2 Actual values of the variables: Buy[BEEF] 0 Buy[CHK] 0 Buy[FISH] 0 Buy[HAM] 0 Buy[MCH] 46.6667 Buy[MTL] 0 Buy[SPG] 0 Buy[TUR] 0 MathProg has also the possibility to have the model and data in two separate files. lp_solve can handle this also. For example: lp_solve -rxli xli_MathProg diet.mod -rxlidata diet.dat This gives as result: Value of objective function: 88.2 Actual values of the variables: Buy[BEEF] 0 Buy[CHK] 0 Buy[FISH] 0 Buy[HAM] 0 Buy[MCH] 46.6667 Buy[MTL] 0 Buy[SPG] 0 Buy[TUR] 0 Generating MathProg modelsThe XLI can also create a MathProg model, however it doesn't use the strength of the language. Constraints are written out line per line. But it can be a starter. For example: lp_solve model.lp -wxli xli_MathProg model.mod This gives as model.mod: /* Variable definitions */ var x >= 0; var y >= 0; /* Objective function */ maximize obj: +143*x +60*y; /* Constraints */ R1: +120*x +210*y <= 15000; R2: +110*x +30*y <= 4000; R3: +x +y <= 75; APIUse the lpsolve API call read_XLI to read a model and write_XLI to write a model. See also External Language Interfaces. IDEAlso from within the IDE, this XLI can be used. However, some entries must be added in LpSolveIDE.ini (in the folder where the IDE is installed). In the [XLI] section the following must be added: lib1=xli_MathProg And a new section for the MathProg XLI must also be added: [xli_MathProg] extension=.mod language=MATHPROG Then make sure that the xli_MathProg.dll is available for the IDE. This must be done by placing this dll in the IDE folder or in the Windows system32 folder. Example models/dataDiet1.modset NUTR; set FOOD; param cost {FOOD} > 0; param f_min {FOOD} >= 0; param f_max {j in FOOD} >= f_min[j]; param n_min {NUTR} >= 0; param n_max {i in NUTR} >= n_min[i]; param amt {NUTR,FOOD} >= 0; var Buy {j in FOOD} >= f_min[j], <= f_max[j]; minimize total_cost: sum {j in FOOD} cost[j] * Buy[j]; subject to diet {i in NUTR}: n_min[i] <= sum {j in FOOD} amt[i,j] * Buy[j] <= n_max[i]; data; set NUTR := A B1 B2 C ; set FOOD := BEEF CHK FISH HAM MCH MTL SPG TUR ; param: cost f_min f_max := BEEF 3.19 0 100 CHK 2.59 0 100 FISH 2.29 0 100 HAM 2.89 0 100 MCH 1.89 0 100 MTL 1.99 0 100 SPG 1.99 0 100 TUR 2.49 0 100 ; param: n_min n_max := A 700 10000 C 700 10000 B1 700 10000 B2 700 10000 ; param amt (tr): A C B1 B2 := BEEF 60 20 10 15 CHK 8 0 20 20 FISH 8 10 15 10 HAM 40 40 35 10 MCH 15 35 15 15 MTL 70 30 15 15 SPG 25 50 25 15 TUR 60 20 15 10 ; end; diet.modset NUTR; set FOOD; param cost {FOOD} > 0; param f_min {FOOD} >= 0; param f_max {j in FOOD} >= f_min[j]; param n_min {NUTR} >= 0; param n_max {i in NUTR} >= n_min[i]; param amt {NUTR,FOOD} >= 0; var Buy {j in FOOD} >= f_min[j], <= f_max[j]; minimize total_cost: sum {j in FOOD} cost[j] * Buy[j]; subject to diet {i in NUTR}: n_min[i] <= sum {j in FOOD} amt[i,j] * Buy[j] <= n_max[i]; diet.datset NUTR := A B1 B2 C ; set FOOD := BEEF CHK FISH HAM MCH MTL SPG TUR ; param: cost f_min f_max := BEEF 3.19 0 100 CHK 2.59 0 100 FISH 2.29 0 100 HAM 2.89 0 100 MCH 1.89 0 100 MTL 1.99 0 100 SPG 1.99 0 100 TUR 2.49 0 100 ; param: n_min n_max := A 700 10000 C 700 10000 B1 700 10000 B2 700 10000 ; param amt (tr): A C B1 B2 := BEEF 60 20 10 15 CHK 8 0 20 20 FISH 8 10 15 10 HAM 40 40 35 10 MCH 15 35 15 15 MTL 70 30 15 15 SPG 25 50 25 15 TUR 60 20 15 10 ; model.lp/* model.lp */ max: 143 x + 60 y; 120 x + 210 y <= 15000; 110 x + 30 y <= 4000; x + y <= 75; |
get_sensitivity_obj, get_ptr_sensitivity_obj, get_sensitivity_objex, get_ptr_sensitivity_objexReturns the sensitivity of the objective function. unsigned char get_sensitivity_obj(lprec *lp, REAL *objfrom, REAL *objtill); unsigned char get_sensitivity_objex(lprec *lp, REAL *objfrom, REAL *objtill, REAL *objfromvalue, REAL *objtillvalue); unsigned char get_ptr_sensitivity_obj(lprec *lp, REAL **ptr_objfrom, REAL **ptr_objtill); unsigned char get_ptr_sensitivity_objex(lprec *lp, REAL **ptr_objfrom, REAL **ptr_objtill, REAL **ptr_objfromvalue, REAL **ptr_objtillvalue); Return Value get_sensitivity_obj, get_ptr_sensitivity_obj, get_sensitivity_objex,
get_ptr_sensitivity_objex return TRUE (1) if the operation was
successful. A return value of FALSE (0) indicates an error. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI objfrom An array that will contain the values of the lower limits on the objective function. ptr_objfrom The address of a pointer that will point to an array that will contain the values of the lower limits of the objective function. objtill An array that will contain the values of the upper limits of the objective function. ptr_objtill The address of a pointer that will point to an array that will contain the values of the upper limits of the objective function. objfromvalue An array that will contain the values of the variables at their lower limit. Only applicable when the value of the variable is 0 (rejected). objtillvalue Not used at this time. ptr_objfromvalue The address of a pointer that will point to an array that will contain the values of the variables at their lower limit. Only applicable when the value of the variable is 0 (rejected). ptr_objtillvalue Not used at this time. Remarks The get_sensitivity_obj, get_ptr_sensitivity_obj, get_sensitivity_objex,
get_ptr_sensitivity_objex functions return the sensitivity of the
objective function. Note that get_ptr_sensitivity_obj and get_ptr_sensitivity_objex return a pointer to memory allocated and maintained by lp_solve. Be careful what you do with it. Don't modify its contents or free the memory. Unexpected behaviour would occur. Also note that this memory pointer is only guaranteed to remain constant until a next lp_solve API call is done. You should call this function again to make sure you have again the correct pointer. Otherwise, this pointer could point to invalid memory. This should not be a problem since this call is very efficient. Example
See Also make_lp, copy_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, is_feasible, get_objective, get_working_objective, get_variables, get_ptr_variables, get_primal_solution, get_ptr_primal_solution, get_var_primalresult, get_sensitivity_rhs, get_ptr_sensitivity_rhs, |
AMPL (A Mathematical Programming Language) is a high-level language for describing mathematical
programs. AMPL allows a mathematical programming model to be specified independently of the data
used for a specific instance of the model. AMPL's language for describing mathematical programs closely
follows that used by humans to describe mathematical programs to each other. For this reason, modellers
may spend more time improving the model and less time on the tedious details of data manipulation and
problem solution.
To start, AMPL needs a mathematical
programming model, which describes variables, objectives and relationships without referring to specific data.
AMPL also needs an instance of the data, or a particular data set. The model and one (or more) data files are
fed into the AMPL program. AMPL works like a compiler: the model and input are put into an intermediate
file that can be read by a solver. The solver actually finds an optimal solution to the problem by reading
in the intermediate file produced by AMPL and applying an appropriate algorithm. The solver outputs the
solution as a text file, which can be viewed directly and cross-referenced with the variables and constraints
specified in the model file.
We will not discuss the specifics of AMPL here but instead refer the reader to AMPL (A Mathematical Programming Language) at the University of Michigan Documentation and the AMPL website http://www.ampl.com.
One of the possible solvers that can be used by AMPL is lpsolve. However note that AMPL allows also defining non-linear models. These are not solvable by lpsolve because lpsolve can only handle MILP models. A message will be given if the AMPL model results in a model that cannot be handled by lpsolve.
To make this possible, a driver program is needed: lpsolve(.exe). This program must be put in the AMPL directory and AMPL can call the lpsolve solver. The newer versions of the lpsolve(.exe) driver call lpsolve via the shared library (lpsolve55.dll under Windows and liblpsolve55.so under Unix/Linux). This has the advantage that the lpsolve driver program doesn't have to be recompiled when an update of lpsolve is provided. The shared library must be somewhere in the path. That is all.
In the following text, ampl: before the AMPL commands is the AMPL prompt. Only the text after the : must be entered.
To select the lpsolve solver, the following command must be executed in AMPL:
ampl: option solver lpsolve;
To solve the model, the following command must be executed in AMPL:
ampl: solve;
Options can be passed to lpsolve. For example to enable scaling, the following command must be executed in AMPL:
ampl: option lpsolve_options 'scale';
Multiple options can be specified by separating them with at least one space:
ampl: option lpsolve_options 'scale scalemode=7 verbose';
A list of all options is given at the end of this document.
ampl: model diet.mod; ampl: data diet.dat; ampl: option solver lpsolve; ampl: option lpsolve_options 'scale scalemode=7'; ampl: solve;
This gives as result:
LP_SOLVE 5.5.0.13: scale scalemode=7 LP_SOLVE 5.5.0.13: optimal, objective 88.2 1 simplex iterations
AMPL has a parameter that is used to indicate the outcome of the optimisation process. It is used as follows
ampl: display solve_result_num
solve_result_num can take the values shown in following table which also presents a short explanation for each value.
|
ampl: model diet.mod; ampl: data diet.dat; ampl: option solver lpsolve; ampl: solve;
This gives as result:
LP_SOLVE 5.5.0.13: optimal, objective 88.2 3 simplex iterations
Note that 3 iterations were needed to solve the model. Now solve the model again:
ampl: solve;
This gives as result:
LP_SOLVE 5.5.0.13: optimal, objective 88.2 0 simplex iterations
Note now that no iterations are needed to solve the model. This because the result of the previous solve is used as a starting point for the new solve. It is even allowed to add or deleted variables and constraints in the model, lpsolve will still try to start from the last result to continue.
If, for some reason, you don't want this and let lpsolve resolve the model from scratch, there are two possibilities to let lpsolve ignore the starting base. Either via an lpsolve option or an AMPL option.
The lpsolve option that can be set is:
ampl: option lpsolve_options 'coldstart';
The AMPL option that can be set is:
ampl: option send_statuses 0;
ampl: solve;
This gives as result:
LP_SOLVE 5.5.0.13: coldstart LP_SOLVE 5.5.0.13: optimal, objective 88.2 3 simplex iterations
Special considerations for integer models. From the moment that a model contains integer variables,
the B&B algorithm must be used to solve this. This algorithm must go trough a tree of possible solutions
each time a solve is done. The last base of the best integer solution can not be used as a starting base for
a resolve. This is not an lpsolve limitation, but a B&B algorithm property...
For this reason, by default, AMPL doesn't provide a starting to the solver and solve is done from scratch.
By default... However, a compromise can be implemented by the solver. And this is also done in lpsolve. Solving
integer models is always started with solving the non-integer model. When this is done, the non-integer variables
are made integer via the B&B algorithm. lpsolve returns the base of the non-integer model and this base is
used as a starting base for the model at the next solve. As said, this is a compromise because it results in
a fast solve of the non-integer model, but the B&B algorithm must still be executed. So even if no
modifications are done to the model and solve is done again, there will be iterations needed by the B&B
algorithm to solve the integers. Because this must be explicitly implemented in the solver, AMPL doesn't
provide the starting base by default for integer models. It must explicitly be activated:
ampl: option send_statuses 2;
Only then, lpsolve will get a starting base when there are integers.
Example:
ampl: model multmip3.mod; ampl: data multmip3.dat; ampl: option solver lpsolve; ampl: solve;
This gives as result:
LP_SOLVE 5.5.0.13: optimal, objective 235625 1986 simplex iterations 592 branch & bound nodes: depth 21
Note that 1986 iterations were needed to solve the model. Now solve the model again:
ampl: solve;
This gives as result:
LP_SOLVE 5.5.0.13: optimal, objective 235625 1986 simplex iterations 592 branch & bound nodes: depth 21
The same as above. So no restart was done. Now activate the starting base for integer models and solve again:
ampl: option send_statuses 2; ampl: solve;
This gives as result:
LP_SOLVE 5.5.0.13: optimal, objective 235625 1922 simplex iterations 592 branch & bound nodes: depth 21
Note that less iterations are needed, but not 0 as in non-integer models. These are the iterations needed for the B&B algorithm.
lpsolve accepts a lot of options. Some options are just on/off switches and for there you just specify the option keyword (for example scale). Other options need a value and this is specified by an equal (=) sign after the option keyword and then the value (for example scalemode=7). Multiple options can be specified by separating them by a space (for example scale scalemode=7).
These options can be displayed from the command line by entering the following:
lpsolve -=
Here is a list of the possible lpsolve options:
bb=... branch-and-bound rule: one of 0 (default) for lowest indexed non-integer variable 1 for selection based on distance from the current bounds 2 for selection based on the largest current bound 3 for selection based on largest fractional value 4 for simple, unweighted pseudo-cost of a variable 5 this is an extended pseudo-costing strategy based on minimizing the number of integer infeasibilities 6 this is an extended pseudo-costing strategy based on maximizing the normal pseudo-cost divided by the number of infeasibilities plus 8 for weight reverse mode 16 when cauto is used, select the oposite direction that autoselect had chosen 32 for greedy mode 64 for pseudo cost mode 128 select the node that has already been selected before the most number of times 256 for randomize mode 1024 when mode 128 is selected, switch off this mode when a first solution is found 2048 for restart mode 4096 select the node that has been selected before the fewest number of times or not at all bfp=... set basis factorization package cauto in IPs, algorithm decides which branch being taken first cfirst in IPs, take ceiling branch first coldstart ignore starting base crash=... determines a starting base: one of 0 (default) none 2 most feasible basis debug debug mode degen perturb degeneracies degenx=... anti-degen handling: one of 0 (default) no anti-degeneracy handling 1 check if there are equality slacks in the basis and try to drive them out in order to reduce chance of degeneracy in Phase 1 2 ColumnCheck 4 Stalling 8 NumFailure 16 LostFeas 32 Infeasible 64 Dynamic 128 During BB depth=... set branch-and-bound depth limit dual prefer the dual simplex for both phases eps=... tolerance for rounding to integer epsb=... minimum tolerance for the RHS epsd=... minimum tolerance for reduced costs epsel=... minimum tolerance for rounding values to zero epsp=... value that is used as perturbation scalar for degenerative problems f specifies that branch-and-bound algorithm stops at first found solution ga=... specifies the absolute MIP gap for branch-and-bound gr=... specifies the relative MIP gap for branch-and-bound improve=... the iterative improvement level: one of 0 improve none 1 Running accuracy measurement of solved equations based on Bx=r (primal simplex), remedy is refactorization. 2 Improve initial dual feasibility by bound flips (highly recommended, and default) 4 Low-cost accuracy monitoring in the dual, remedy is refactorization 8 By default there is a check for primal/dual feasibility at optimum only for the relaxed problem, this also activates the test at the node level n=... specify which solution number to return o=... specifies that branch-and-bound algorithm stops when objective value is better than value objno=... objective number: 0 = none, 1 (default) = first obound=... a lower bound for the objective function may speed up the calculations parse_only parse input file but do not solve piv=... simplex pivot rule: one of 0 select first 1 select according to Dantzig 2 (default) select Devex pricing from Paula Harris 3 select steepest edge piva temporarily use first index if cycling is detected pivf in case of Steepest Edge, fall back to DEVEX in primal pivla scan entering/leaving columns alternatingly left/right pivll scan entering/leaving columns left rather than right pivm multiple pricing pivr adds a small randomization effect to the selected pricer presolve presolve problem before start optimizing presolvel also eliminate linearly dependent rows presolver if the phase 1 solution process finds that a constraint is redundant then this constraint is deleted prim prefer the primal simplex for both phases printsol=... print solution: one of 0 (default) print nothing 1 only objective value 2 obj value+variables 3 obj value+variables+constraints 4 obj value+variables+constraints+duals 5 obj value+variables+constraints+duals+lp model 6 obj value+variables+constraints+duals+lp model+scales 7 obj value+variables+constraints+duals+lp model+scales+ lp tableau prlp print the LP psols print (intermediate) feasible solutions psolsa print (intermediate) feasible solutions (non-zeros) r=... max nbr of pivots between a re-inversion of the matrix rparname=... parameter file to read options from rparoptions=... options parameter file scale scale the problem scalemode=... scale mode: one of 1 for scale to convergence using largest absolute value 2 for scale based on the simple numerical range 3 (default) for numerical range-based scaling 4 for geometric scaling 7 for Curtis & Reid scaling plus 16 for scale to convergence using logarithmic mean of all values 32 for also do Power scaling 64 to make sure that no scaled number is above 1 128 to scale integer variables simplexdd set Phase1 Dual, Phase2 Dual simplexdp set Phase1 Dual, Phase2 Primal simplexpd set Phase1 Primal, Phase2 Dual simplexpp set Phase1 Primal, Phase2 Primal timeout=... timeout after sec seconds when not solution found trace trace pivot selections trej=... minimum pivot value verbose verbose mode version report version details wafter write model after solve (usefull if presolve used) wantsol=... solution report without -AMPL: sum of 1 ==> write .sol file 2 ==> print primal variable values 4 ==> print dual variable values 8 ==> do not print solution message wfmps=... write to MPS file in free format wlp=... write to LP filename wmps=... write to MPS file in fixed format wparname=... parameter file to write options to wparoptions=... options parameter file wxli=... write file with xli library wxliname=... xli library wxliopt=... options for xli library
Normally, the lpsolve program is called from AMPL. However the program can also be called stand-alone. When the command is invoked without an option or with the option -?, a list of the possible options is shown:
usage: lpsolve [options] stub [-AMPL] [<assignment> ...] Options: -- {end of options} -= {show name= possibilities} -? {show usage} -e {suppress echoing of assignments} -s {write .sol file (without -AMPL)} -v {just show version}
stub and the -AMPL option is used when the program is called from AMPL.
The -v option shows the version of lpsolve.
The -= option shows all the options that can be passed to lpsolve from within AMPL.
These options can also be specified in an environment variable lpsolve_options.
To call the lpsolve command to solve a model, you first must have a stub file that can be read by lpsolve.
This stub file can be created by AMPL as follows:
ampl: model models\diet.mod; ampl: data models\diet.dat; ampl: write bdiet; ampl: quit
This created a binary file diet.nl. As an alternative the command write gdiet; can be used. This creates an ascii file that also can be read. However it is somewhat slower to read, especially when the models are larger.
This creates a file diet.nl in the current directory. This file is the stub file needed by lpsolve:
lpsolve lpsolve diet.nl
This gives:
LP_SOLVE 5.5.0.13: optimal, objective 88.19999999999999 3 simplex iterations
Options can be passed to lpsolve via the environment variable lpsolve_options:
set lpsolve_options=scale scalemode=7 verbose
Then the result of the previous lpsolve command is:
scale scalemode=7 verbose Model name: '' - run #1 Objective: Minimize(R0) Submitted: Model size: 4 constraints, 8 variables, 39 non-zeros. Constraints: 0 equality, 0 GUB, 0 SOS. Variables: 0 integer, 0 semi-cont., 0 SOS. Using DUAL simplex for phase 1 and PRIMAL simplex for phase 2. Optimal solution with dual simplex at iteration 1 lp_solve solution 88.2 final at iteration 1, 0 nodes explor ed Excellent numeric accuracy ||*|| = 1.13687e-013 Memo: Largest [etaPFI v1.0] inv(B) had 0 NZ entries, 0.0x largest basis. In the total iteration count 1, 0 (0.0%) were minor/bound swaps. There were 0 refactorizations, 0 triggered by time and 0 by density. ... on average 1.0 major pivots per refactorization. Total solver time was 0.000 seconds. LP_SOLVE 5.5.0.13: optimal, objective 88.19999999999999 1 simplex iterations
In this mode, the lpsolve option wantsol shows the solution:
set lpsolve_options=wantsol=2 lpsolve diet.nl
This gives:
wantsol=2 LP_SOLVE 5.5.0.13: optimal, objective 88.19999999999999 3 simplex iterations variable value _svar[1] 0 _svar[2] 0 _svar[3] 0 _svar[4] 0 _svar[5] 46.666666666666664 _svar[6] 0 _svar[7] -3.552713678800501e-15 _svar[8] 0
The -e option results in not echoing the options passed to lpsolve:
set lpsolve_options=wantsol=2 lpsolve -e diet.nl
This gives:
LP_SOLVE 5.5.0.13: optimal, objective 88.19999999999999 3 simplex iterations variable value _svar[1] 0 _svar[2] 0 _svar[3] 0 _svar[4] 0 _svar[5] 46.666666666666664 _svar[6] 0 _svar[7] -3.552713678800501e-15 _svar[8] 0
lpsolve options can also be passed at the command line, they don't overrule the lpsolve_options environment variable, they are added:
set lpsolve_options=wantsol=2 lpsolve diet.nl "verbose scale"
This gives:
wantsol=2 verbose scale Model name: '' - run #1 Objective: Minimize(R0) Submitted: Model size: 4 constraints, 8 variables, 39 non-zeros. Constraints: 0 equality, 0 GUB, 0 SOS. Variables: 0 integer, 0 semi-cont., 0 SOS. Using DUAL simplex for phase 1 and PRIMAL simplex for phase 2. Optimal solution with dual simplex at iteration 1 lp_solve solution 88.2 final at iteration 1, 0 nodes explor ed Excellent numeric accuracy ||*|| = 1.13687e-013 Memo: Largest [etaPFI v1.0] inv(B) had 0 NZ entries, 0.0x largest basis. In the total iteration count 1, 0 (0.0%) were minor/bound swaps. There were 0 refactorizations, 0 triggered by time and 0 by density. ... on average 1.0 major pivots per refactorization. Total solver time was 0.000 seconds. LP_SOLVE 5.5.0.13: optimal, objective 88.19999999999997 1 simplex iterations variable value _svar[1] 0 _svar[2] 0 _svar[3] 0 _svar[4] 0 _svar[5] 46.66666666666666 _svar[6] 0 _svar[7] 0 _svar[8] 0
Besides the specific lpsolve files, you also need the AMPL solvers files that must be linked with it.
These AMPL solvers files can be downloaded from various locations. The easiest way is via
ftp://netlib.bell-labs.com/netlib/ampl/solvers.tar.
untar them in directory lp_solve_5.5/extra/AMPL. This will put the files in lp_solve_5.5/extra/AMPL/solvers.
Then in the solvers directory, gunzip all the files with extension .gz.
Then, still in the solvers directory, execute the appropriate Makefile.
For example under Windows:
nmake /f makefile.vc
Under Unix this would be:
make -f makefile.u
This will generate amplsolv.lib under Windows and amplsolver.so under Unix systems.
However, Under windows, you must first create a file details.c by hand. It must contain the following single line:
char sysdetails_ASL[] = "MS VC++ 6.0";
See README for more information how to build the AMPL solvers files.
Then install the files from archive lp_solve_5.5_AMPL_source.tar.gz
When this is done, goto the lpsolve directory and execute the appropriate makefile.
There are two possibilities: generate a driver that links lpsolve statically and one that links lpsolve dynamically.
When linked dynamically, the lpsolve dll or shared library is used at runtime. When linked statically, the lpsolve static
library is linked at compile time with the AMPL lpsolve driver. For example:
nmake /f makefile5dyn.vc
This will generate lpsolve.exe (Windows) or lpsolve (Unix). Put this in the AMPL directory.
Xpress lp filesThe Xpress LP file format provides a facility for entering a problem in a natural, algebraic LP formulation from the keyboard. The problem can be modified and saved from within lpsolve. This procedure is one way to create a file in a format that lpsolve can read. An alternative technique is to create a similar file using a standard text editor and to read it into lpsolve. The Xpress LP format is provided as an input alternative to the MPS file format. An LP format file may be easier to generate than an MPS file if your problem already exists in an algebraic format or if you have an application that generates the problem file more readily in algebraic format (such as a C application). Note that the Xpress LP format is not the same as the lpsolve LP format. See LP file format for a description about the native lpsolve lp format. To read/write this format from lpsolve, you need an XLI (see External Language Interfaces). The XLI for the Xpress format is called xli_Xpress. OptionsThe XLI accepts several options: Reading-objconst Allow constants in the objective (default). -noobjconst Don't allow constants in the objective. From the documentation of the format it is not sure if Xpress allows a constant in the objective. Tests have shown that it allows a constant as first term in the objective function. Note that the lp_solve XLI allows a constant in the objective by default and it can be anywere in the objective. Use the option -noobjconst if this should not be allowed. The parser will then give an error. Writing-objconst Allow constants in the objective. -noobjconst Don't use constants in the objective (default). From the documentation of the format it is not sure if Xpress allows a constant in the objective. Tests have shown that it allows a constant as first term in the objective function. The lp_solve XLI writes the constant as first term when the option -objconst is active. By default or when the option -noobjconst is used, a constant in the objective is translated to a variable objconst_term with a bound equal to the constant set to it. So no error is generated when there is a constant. Examplelp_solve -rxli xli_Xpress input.lp lp_solve -mps input.mps -wxli xli_Xpress output.lp -wxliopt "-objconst" Syntax Rules of LP File Formatlpsolve will accept any problem saved in an ASCII file provided that it adheres to the following syntax rules.
Some examplesExample 1Minimize COST: XONE + 4 YTWO + 9 ZTHREE + 2 Subject To LIM1: XONE + YTWO <= 5 LIM2: XONE + ZTHREE >= 10 MYEQN: - YTWO + ZTHREE = 7 Bounds 0 <= XONE <= 4 -1 <= YTWO <= 1 End Example 2Minimize obj: - 2 x3 Subject To c1: x2 - x1 <= 10 c2: x1 + x2 + x3 <= 20 Bounds x1 <= 30 2 <= x3 <= 3 s.i. x3 x1 >= 2.1 End Example 3Minimize obj: - 2 x3 Subject To c1: x2 - x1 <= 10 \SOS sos101: 4 x2 + 2 x3 = S2 c2: x1 + x2 + x3 <= 20 sos102: x1 + x2 + x3 = S1 sos201: 1.2 x3 +1.3 x2 + 1.4 x1 = S2 Bounds x1 <= 30 2 <= x3 <= 3 End |
We shall illustrate the method of linear programming by means of a simple example, giving a combination graphical/numerical solution, and then solve the problem in lpsolve in different ways. This via ASCII files and from different programming languages.
Suppose a farmer has 75 acres on which to plant two crops: wheat and barley. To produce these crops, it costs the farmer (for seed, fertilizer, etc.) $120 per acre for the wheat and $210 per acre for the barley. The farmer has $15000 available for expenses. But after the harvest, the farmer must store the crops while awaiting favourable market conditions. The farmer has storage space for 4000 bushels. Each acre yields an average of 110 bushels of wheat or 30 bushels of barley. If the net profit per bushel of wheat (after all expenses have been subtracted) is $1.30 and for barley is $2.00, how should the farmer plant the 75 acres to maximize profit?
We begin by formulating the problem mathematically. First we express the objective, that is the profit, and the constraints algebraically, then we graph them, and lastly we arrive at the solution by graphical inspection and a minor arithmetic calculation.
Let x denote the number of acres allotted to wheat and y the number of acres allotted to barley. Then the expression to be maximized, that is the profit, is clearly
P = (110)(1.30)x + (30)(2.00)y = 143x + 60y.
There are three constraint inequalities, specified by the limits on expenses, storage and acreage. They are respectively:
120x + 210y <= 15000
110x + 30y <= 4000
x + y <= 75
Strictly speaking there are two more constraint inequalities forced by the fact that the farmer cannot plant a negative number of acres, namely:
x >= 0, y >= 0.
Next we graph the regions specified by the constraints. The last two say that we only need to consider the first quadrant in the x-y plane. Here's a graph delineating the triangular region in the first quadrant determined by the first inequality.
Now let's put in the other two constraint inequalities.
The black area is the solution space that holds valid solutions. This means that any point in this area fulfils the constraints.
Now let's superimpose on top of this picture a contour plot of the objective function P.
The lines give a picture of the objective function. All solutions that intersect with the black area are valid solutions, meaning that this result also fulfils the set constraints. The more the lines go to the right, the higher the objective value is. The optimal solution or best objective is a line that is still in the black area, but with an as large as possible value.
It seems apparent that the maximum value of P will occur on the level curve (that is, level
line) that passes through the vertex of the polygon that lies near (22,53).
It is the intersection of x + y = 75 and 110*x + 30*y = 4000
This is a corner point of the diagram. This is not a coincidence. The simplex algorithm, which is used
by lpsolve, starts from a theorem that the optimal solution is such a corner point.
In fact we can compute the result:
x + y = 75 (1) 110*x + 30*y = 4000 (2)
From (1), y can be expressed in function of x:
y = 75 - x (3)
This equation can be substituted in (2):
110*x + 30*(75 - x) = 4000
Or:
80*x = 1750
Or:
x = 21.875
From (3), y can be derived:
y = 75 - 21.875 = 53.125
The acreage that results in the maximum profit is 21.875 for wheat and 53.125 for barley. In that case the profit is:
P = 143*x + 60*y
Or:
P = 143*21.875 + 60*53.125 = 6326.625That is, $6315.625.
Now, lpsolve comes into the picture to solve this linear programming problem more generally.
First let us show this problem in its mathematical format:
max(143x + 60y) s.t. 120x + 210y <= 15000 110x + 30y <= 4000 x + y <= 75 x >= 0 y >= 0
There are several ways to model a linear problem via lpsolve:
There exist a lot of formats to model an lp problem into. Almost each solver has its format on its own.
The MPS format is supported by most lp solvers and thus very universal. The model is provided to the solver via an ASCII file. This format is very old and difficult to read by humans. See MPS file format for a complete description about the format. This problem is formulated as follows in MPS format:
* model.mps NAME ROWS N R0 L R1 L R2 L R3 COLUMNS x R0 143.00000000 R1 120.00000000 x R2 110.00000000 R3 1.0000000000 y R0 60.00000000 R1 210.00000000 y R2 30.000000000 R3 1.0000000000 RHS RHS R1 15000.000000 R2 4000.0000000 RHS R3 75.000000000 ENDATA
Save this as ASCII file with name model.mps
To read this format in lpsolve, the API functions read_mps, read_freemps, read_MPS, read_freeMPS can be used. The lpsolve distribution comes with two applications that use this API call to read a model:
To read this MPS model via the lp_solve command line program and calculate the solution, enter the following command:
lp_solve -max -mps model.mps
This gives:
Value of objective function: 6315.63 Actual values of the variables: x 21.875 y 53.125
The lp_solve program has a lot of options that can be set. See lp_solve command
Under Windows, there is also a graphical IDE that can read an MPS file. See LPSolve IDE for more information.
The lp format is the native lpsolve format to provide LP models via an ASCII file to the solver. It is very readable and its syntax is very similar to the Mathematical formulation. See LP file format for a complete description about the format. This model is formulated as follows in lp-format:
/* model.lp */ max: 143 x + 60 y; 120 x + 210 y <= 15000; 110 x + 30 y <= 4000; x + y <= 75;
Save this as ASCII file with name model.lp
To read this format in lpsolve, the API functions read_lp, read_LP can be used. The lpsolve distribution comes with two applications that use this API call to read a model:
To read this lp model via the lp_solve command line program and calculate the solution, enter the following command:
lp_solve model.lp
This gives:
Value of objective function: 6315.63 Actual values of the variables: x 21.875 y 53.125
The lp_solve program has a lot of options that can be set. See lp_solve command
Under Windows, there is also a graphical IDE that can read an lp-file. See LPSolve IDE for more information.
The CPLEX lp format is another format to provide LP models via an ASCII file to the solver. It is very readable and its syntax is very similar to the Mathematical formulation. It is a format used by the CPLEX solver. See CPLEX lp files for a complete description about the format. This model is formulated as follows in CPLEX lp format:
\* model.lpt *\ Maximize +143 x +60 y Subject To +120 x +210 y <= 15000 +110 x +30 y <= 4000 +x +y <= 75 End
Save this as ASCII file with name model.lpt
lpsolve doesn't has an API call to read/write this format. However, the lpsolve distribution has an XLI that can do this. See External Language Interfaces for a description about XLIs. This uses the API call read_XLI. The xli to read/write this format is xli_CPLEX. The lpsolve distribution comes with two applications that use this API call to read a model:
To read this CPLEX lp model via the lp_solve command line program and calculate the solution, enter the following command:
lp_solve -rxli xli_CPLEX model.lpt
This gives:
Value of objective function: 6315.63 Actual values of the variables: x 21.875 y 53.125
The lp_solve program has a lot of options that can be set. See lp_solve command
Under Windows, there is also a graphical IDE that can read a CPLEX lp file via an XLI. See LPSolve IDE for more information.
The LINDO FILE format is another format to provide LP models via an ASCII file to the solver. It is very readable and its syntax is very similar to the Mathematical formulation. It is a format used by the LINDO solver. See LINDO lp files for a complete description about the format. This model is formulated as follows in LINDO FILE format:
! model.lnd MAXIMIZE +143 x +60 y SUBJECT TO +120 x +210 y <= 15000 +110 x +30 y <= 4000 +x +y <= 75 END
Save this as ASCII file with name model.lpt
lpsolve doesn't has an API call to read/write this format. However, the lpsolve distribution has an XLI that can do this. See External Language Interfaces for a description about XLIs. This uses the API call read_XLI. The xli to read/write this format is xli_LINDO. The lpsolve distribution comes with two applications that use this API call to read a model:
To read this LINDO lp model via the lp_solve command line program and calculate the solution, enter the following command:
lp_solve -rxli xli_LINDO model.lnd
This gives:
Value of objective function: 6315.63 Actual values of the variables: x 21.875 y 53.125
The lp_solve program has a lot of options that can be set. See lp_solve command
Under Windows, there is also a graphical IDE that can read a LINDO lp file via an XLI. See LPSolve IDE for more information.
The GNU MathProg format is another format to provide LP models via an ASCII file to the solver. It is very readable and its syntax is very similar to the Mathematical formulation. It is a format used by the GLPK solver and a subset of AMPL. It has also the possibility to use loops. See Modeling Language GNU MathProg This model is formulated as follows in GNU MathProg format:
/* model.mod */ var x >= 0; var y >= 0; maximize obj: +143*x +60*y; R1: +120*x +210*y <= 15000; R2: +110*x +30*y <= 4000; R3: +x +y <= 75;
Save this as ASCII file with name model.mod
lpsolve doesn't has an API call to read/write this format. However, the lp_solve distribution has an XLI that can do this. See External Language Interfaces for a description about XLIs. This uses the API call read_XLI. The xli to read/write this format is xli_MathProg. The lpsolve distribution comes with two applications that use this API call to read a model:
To read this GNU MathProg model via the lp_solve command line program and calculate the solution, enter the following command:
lp_solve -rxli xli_MathProg model.mod
This gives:
Value of objective function: 6315.63 Actual values of the variables: x 21.875 y 53.125
The lp_solve program has a lot of options that can be set. See lp_solve command
Under Windows, there is also a graphical IDE that can read a GNU MathProg file via an XLI. See LPSolve IDE for more information.
The LPFML XML format is another format to provide LP models via an ASCII file to the solver. This format is very recent and uses XML layout. It is not very readable by us, but because of the XML structure very flexible. See LPFML: A W3C XML Schema for Linear Programming for more information. This model is formulated as follows in LPFML XML format:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <mathProgram xmlns="http://FML/lpfml.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://FML/lpfml.xsd lpfml.xsd"> <linearProgramDescription> <source></source> <maxOrMin>max</maxOrMin> <numberRows>3</numberRows> <numberVars>2</numberVars> </linearProgramDescription> <linearProgramData> <rows> <row rowName="R1" rowUB="15000"/> <row rowName="R2" rowUB="4000"/> <row rowName="R3" rowUB="75"/> </rows> <columns> <col colName="x" colType="C" objVal="143"/> <col colName="y" colType="C" objVal="60"/> </columns> <amatrix> <sparseMatrix> <pntANonz> <el>3</el> <el>6</el> </pntANonz> <rowIdx> <el>0</el> <el>1</el> <el>2</el> <el>0</el> <el>1</el> <el>2</el> </rowIdx> <nonz> <el>120</el> <el>110</el> <el>1</el> <el>210</el> <el>30</el> <el>1</el> </nonz> </sparseMatrix> </amatrix> </linearProgramData> </mathProgram>
Save this as ASCII file with name model.xml
lpsolve doesn't has an API call to read/write this format. However, the lp_solve distribution has an XLI that can do this. See External Language Interfaces for a description about XLIs. This uses the API call read_XLI. The xli to read/write this format is xli_LPFML. The lpsolve distribution comes with two applications that use this API call to read a model:
To read this LPFML XML model via the lp_solve command line program and calculate the solution, enter the following command:
lp_solve -rxli xli_LPFML model.xml
This gives:
Value of objective function: 6315.63 Actual values of the variables: x 21.875 y 53.125
The lp_solve program has a lot of options that can be set. See lp_solve command
Under Windows, there is also a graphical IDE that can read a LPFML XML file via an XLI. See LPSolve IDE for more information.
There are several commercial and free Mathematical programming applications out there which can be used to solve lp problems. An lpsolve driver is made for several of them:
In several cases it is required that the solver is called from within the programming language in which an application is build. All the data is in memory and no files are created to provide data to the solver. lpsolve has a very rich, yet easy, API to do this. See lp_solve API reference for an overview of the API. lpsolve is a library of API routines. This library is called from the programming language. See Calling the lpsolve API from your application for more information. Above example is now formulated in several programming languages:
The example model can be formulated as follows in C:
/* demo.c */ #include "lp_lib.h" int demo() { lprec *lp; int Ncol, *colno = NULL, j, ret = 0; REAL *row = NULL; /* We will build the model row by row So we start with creating a model with 0 rows and 2 columns */ Ncol = 2; /* there are two variables in the model */ lp = make_lp(0, Ncol); if(lp == NULL) ret = 1; /* couldn't construct a new model... */ if(ret == 0) { /* let us name our variables. Not required, but can be useful for debugging */ set_col_name(lp, 1, "x"); set_col_name(lp, 2, "y"); /* create space large enough for one row */ colno = (int *) malloc(Ncol * sizeof(*colno)); row = (REAL *) malloc(Ncol * sizeof(*row)); if((colno == NULL) || (row == NULL)) ret = 2; } if(ret == 0) { set_add_rowmode(lp, TRUE); /* makes building the model faster if it is done rows by row */ /* construct first row (120 x + 210 y <= 15000) */ j = 0; colno[j] = 1; /* first column */ row[j++] = 120; colno[j] = 2; /* second column */ row[j++] = 210; /* add the row to lpsolve */ if(!add_constraintex(lp, j, row, colno, LE, 15000)) ret = 3; } if(ret == 0) { /* construct second row (110 x + 30 y <= 4000) */ j = 0; colno[j] = 1; /* first column */ row[j++] = 110; colno[j] = 2; /* second column */ row[j++] = 30; /* add the row to lpsolve */ if(!add_constraintex(lp, j, row, colno, LE, 4000)) ret = 3; } if(ret == 0) { /* construct third row (x + y <= 75) */ j = 0; colno[j] = 1; /* first column */ row[j++] = 1; colno[j] = 2; /* second column */ row[j++] = 1; /* add the row to lpsolve */ if(!add_constraintex(lp, j, row, colno, LE, 75)) ret = 3; } if(ret == 0) { set_add_rowmode(lp, FALSE); /* rowmode should be turned off again when done building the model */ /* set the objective function (143 x + 60 y) */ j = 0; colno[j] = 1; /* first column */ row[j++] = 143; colno[j] = 2; /* second column */ row[j++] = 60; /* set the objective in lpsolve */ if(!set_obj_fnex(lp, j, row, colno)) ret = 4; } if(ret == 0) { /* set the object direction to maximize */ set_maxim(lp); /* just out of curioucity, now show the model in lp format on screen */ /* this only works if this is a console application. If not, use write_lp and a filename */ write_LP(lp, stdout); /* write_lp(lp, "model.lp"); */ /* I only want to see important messages on screen while solving */ set_verbose(lp, IMPORTANT); /* Now let lpsolve calculate a solution */ ret = solve(lp); if(ret == OPTIMAL) ret = 0; else ret = 5; } if(ret == 0) { /* a solution is calculated, now lets get some results */ /* objective value */ printf("Objective value: %f\n", get_objective(lp)); /* variable values */ get_variables(lp, row); for(j = 0; j < Ncol; j++) printf("%s: %f\n", get_col_name(lp, j + 1), row[j]); /* we are done now */ } /* free allocated memory */ if(row != NULL) free(row); if(colno != NULL) free(colno); if(lp != NULL) { /* clean up such that all used memory by lpsolve is freed */ delete_lp(lp); } return(ret); } int main() { demo(); }
When this is run, the following is shown on screen:
/* Objective function */ max: +143 x +60 y; /* Constraints */ +120 x +210 y <= 15000; +110 x +30 y <= 4000; +x +y <= 75; Objective value: 6315.625000 x: 21.875000 y: 53.125000
Note that this example is very limited. It is also possible to set bounds on variables, ranges on constraints, define variables as integer, get more result information, changing solver options and parameters and much more. See lp_solve API reference for an overview of the API to do this.
The example model can be formulated as follows in Java:
/* demo.java */ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import lpsolve.*; public class Demo { public Demo() { } public int execute() throws LpSolveException { LpSolve lp; int Ncol, j, ret = 0; /* We will build the model row by row So we start with creating a model with 0 rows and 2 columns */ Ncol = 2; /* there are two variables in the model */ /* create space large enough for one row */ int[] colno = new int[Ncol]; double[] row = new double[Ncol]; lp = LpSolve.makeLp(0, Ncol); if(lp.getLp() == 0) ret = 1; /* couldn't construct a new model... */ if(ret == 0) { /* let us name our variables. Not required, but can be useful for debugging */ lp.setColName(1, "x"); lp.setColName(2, "y"); lp.setAddRowmode(true); /* makes building the model faster if it is done rows by row */ /* construct first row (120 x + 210 y <= 15000) */ j = 0; colno[j] = 1; /* first column */ row[j++] = 120; colno[j] = 2; /* second column */ row[j++] = 210; /* add the row to lpsolve */ lp.addConstraintex(j, row, colno, LpSolve.LE, 15000); } if(ret == 0) { /* construct second row (110 x + 30 y <= 4000) */ j = 0; colno[j] = 1; /* first column */ row[j++] = 110; colno[j] = 2; /* second column */ row[j++] = 30; /* add the row to lpsolve */ lp.addConstraintex(j, row, colno, LpSolve.LE, 4000); } if(ret == 0) { /* construct third row (x + y <= 75) */ j = 0; colno[j] = 1; /* first column */ row[j++] = 1; colno[j] = 2; /* second column */ row[j++] = 1; /* add the row to lpsolve */ lp.addConstraintex(j, row, colno, LpSolve.LE, 75); } if(ret == 0) { lp.setAddRowmode(false); /* rowmode should be turned off again when done building the model */ /* set the objective function (143 x + 60 y) */ j = 0; colno[j] = 1; /* first column */ row[j++] = 143; colno[j] = 2; /* second column */ row[j++] = 60; /* set the objective in lpsolve */ lp.setObjFnex(j, row, colno); } if(ret == 0) { /* set the object direction to maximize */ lp.setMaxim(); /* just out of curioucity, now generate the model in lp format in file model.lp */ lp.writeLp("model.lp"); /* I only want to see important messages on screen while solving */ lp.setVerbose(LpSolve.IMPORTANT); /* Now let lpsolve calculate a solution */ ret = lp.solve(); if(ret == LpSolve.OPTIMAL) ret = 0; else ret = 5; } if(ret == 0) { /* a solution is calculated, now lets get some results */ /* objective value */ System.out.println("Objective value: " + lp.getObjective()); /* variable values */ lp.getVariables(row); for(j = 0; j < Ncol; j++) System.out.println(lp.getColName(j + 1) + ": " + row[j]); /* we are done now */ } /* clean up such that all used memory by lpsolve is freed */ if(lp.getLp() != 0) lp.deleteLp(); return(ret); } public static void main(String[] args) { try { new Demo().execute(); } catch (LpSolveException e) { e.printStackTrace(); } } }
When this is run, the following is shown on screen:
Objective value: 6315.625 x: 21.875000000000007 y: 53.12499999999999
And a file model.lp is created with the following contents:
/* Objective function */ max: +143 x +60 y; /* Constraints */ +120 x +210 y <= 15000; +110 x +30 y <= 4000; +x +y <= 75;
Note that this example is very limited. It is also possible to set bounds on variables, ranges on constraints, define variables as integer, get more result information, changing solver options and parameters and much more. See lp_solve API reference for an overview of the API to do this.
Also note that the API names in Java are a bit different than in the native lpsolve API and the lp argument is not there. See the lpsolve Java wrapper documentation for more details.
The example model can be formulated as follows in Delphi or Free Pascal:
program demo; {$APPTYPE CONSOLE} uses SysUtils, lpsolve; var Ncol, j, ret: integer; colno: PIntArray; row: PFloatArray; lp: THandle; begin ret := 0; colno := nil; row := nil; (* We will build the model row by row So we start with creating a model with 0 rows and 2 columns *) Ncol := 2; (* there are two variables in the model *) lp := make_lp(0, Ncol); if (lp = 0) then ret := 1; (* couldn't construct a new model... *) (* let us name our variables. Not required, but can be usefull for debugging *) set_col_name(lp, 1, 'x'); set_col_name(lp, 2, 'y'); if (ret = 0) then begin (* create space large enough for one row *) GetMem(colno, SizeOf(integer) * Ncol); GetMem(row, SizeOf(double) * Ncol); if ((colno = nil) or (row = nil)) then ret := 2; end; if (ret = 0) then begin set_add_rowmode(lp, true); (* makes building the model faster if it is done rows by row *) (* construct first row (120 x + 210 y <= 15000) *) j := 0; colno^[j] := 1; (* first column *) row^[j] := 120; j := j + 1; colno^[j] := 2; (* second column *) row^[j] := 210; j := j + 1; (* add the row to lp_solve *) if (not add_constraintex(lp, j, row, colno, LE, 15000)) then ret := 3; end; if (ret = 0) then begin (* construct second row (110 x + 30 y <= 4000) *) j := 0; colno^[j] := 1; (* first column *) row^[j] := 110; j := j + 1; colno^[j] := 2; (* second column *) row^[j] := 30; j := j + 1; (* add the row to lp_solve *) if (not add_constraintex(lp, j, row, colno, LE, 4000)) then ret := 3; end; if (ret = 0) then begin (* construct third row (x + y <= 75) *) j := 0; colno^[j] := 1; (* first column *) row^[j] := 1; j := j + 1; colno^[j] := 2; (* second column *) row^[j] := 1; j := j + 1; (* add the row to lp_solve *) if (not add_constraintex(lp, j, row, colno, LE, 75)) then ret := 3; end; if (ret = 0) then begin set_add_rowmode(lp, false); (* rowmode should be turned off again when done building the model *) (* set the objective function (143 x + 60 y) *) j := 0; colno^[j] := 1; (* first column *) row^[j] := 143; j := j + 1; colno^[j] := 2; (* second column *) row^[j] := 60; j := j + 1; (* set the objective in lp_solve *) if (not set_obj_fnex(lp, j, row, colno)) then ret := 4; end; if (ret = 0) then begin (* set the object direction to maximize *) set_maxim(lp); (* just out of curioucity, now show the model in lp format *) write_lp(lp, 'model.lp'); (* I only want to see importand messages on screen while solving *) set_verbose(lp, IMPORTANT); (* Now let lp_solve calculate a solution *) ret := solve(lp); if (ret = OPTIMAL) then ret := 0 else ret := 5; end; if (ret = 0) then begin (* a solution is calculated, now lets get some results *) (* objective value *) writeln(format('Objective value: %f', [get_objective(lp)])); (* variable values *) get_variables(lp, row); for j := 0 to Ncol-1 do writeln(format('%s: %f', [get_col_name(lp, j + 1), row^[j]])); (* we are done now *) end; (* free allocated memory *) if (row <> nil) then FreeMem(row); if (colno <> nil) then FreeMem(colno); if(lp <> 0) then begin (* clean up such that all used memory by lp_solve is freeed *) delete_lp(lp); end; end.
When this is run, the following is shown:
Objective value: 6315.63 x: 21.88 y: 53.12
And a file model.lp is created with the following contents:
/* Objective function */ max: +143 x +60 y; /* Constraints */ +120 x +210 y <= 15000; +110 x +30 y <= 4000; +x +y <= 75;
Note that a unit lpsolve.pas+lpsolve.inc is needed for this to work. This is available via the Delphi example.
Note that this example is very limited. It is also possible to set bounds on variables, ranges on constraints, define variables as integer, get more result information, changing solver options and parameters and much more. See lp_solve API reference for an overview of the API to do this.
The example model can be formulated as follows in VB or VBScript:
Option Explicit 'demo Private lpsolve As lpsolve55 Sub Main() Set lpsolve = New lpsolve55 lpsolve.Init "." Demo Set lpsolve = Nothing End Sub Private Function Demo() As Integer Dim lp As Long Dim Ncol As Long, colno() As Long Dim j As Integer, ret As Integer Dim row() As Double With lpsolve ' We will build the model row by row ' So we start with creating a model with 0 rows and 2 columns Ncol = 2 ' there are two variables in the model lp = .make_lp(0, Ncol) If lp = 0 Then ret = 1 ' couldn't construct a new model... End If If ret = 0 Then ' let us name our variables. Not required, but can be useful for debugging .set_col_name lp, 1, "x" .set_col_name lp, 2, "y" ' create space large enough for one row ReDim colno(0 To Ncol - 1) ReDim row(0 To Ncol - 1) End If If ret = 0 Then .set_add_rowmode lp, True ' makes building the model faster if it is done rows by row ' construct first row (120 x + 210 y <= 15000) j = 0 colno(j) = 1 ' first column row(j) = 120 j = j + 1 colno(j) = 2 ' second column row(j) = 210 j = j + 1 ' add the row to lpsolve If .add_constraintex(lp, j, row(0), colno(0), LE, 15000) = False Then ret = 3 End If End If If ret = 0 Then ' construct second row (110 x + 30 y <= 4000) j = 0 colno(j) = 1 ' first column row(j) = 110 j = j + 1 colno(j) = 2 ' second column row(j) = 30 j = j + 1 ' add the row to lpsolve If .add_constraintex(lp, j, row(0), colno(0), LE, 4000) = False Then ret = 3 End If End If If ret = 0 Then ' construct third row (x + y <= 75) j = 0 colno(j) = 1 ' first column row(j) = 1 j = j + 1 colno(j) = 2 ' second column row(j) = 1 j = j + 1 ' add the row to lpsolve If .add_constraintex(lp, j, row(0), colno(0), LE, 75) = False Then ret = 3 End If End If If ret = 0 Then .set_add_rowmode lp, False ' rowmode should be turned off again when done building the model ' set the objective function (143 x + 60 y) j = 0 colno(j) = 1 ' first column row(j) = 143 j = j + 1 colno(j) = 2 ' second column row(j) = 60 j = j + 1 ' set the objective in lpsolve If .set_obj_fnex(lp, j, row(0), colno(0)) = False Then ret = 4 End If End If If ret = 0 Then ' set the object direction to maximize .set_maxim lp ' just out of curioucity, now show the model in lp format on screen ' this only works if this is a console application. If not, use write_lp and a filename .write_lp lp, "model.lp" ' I only want to see important messages on screen while solving .set_verbose lp, 3 ' Now let lpsolve calculate a solution ret = .solve(lp) If ret = OPTIMAL Then ret = 0 Else ret = 5 End If End If If ret = 0 Then ' a solution is calculated, now lets get some results ' objective value Debug.Print "Objective value: " & .get_objective(lp) ' variable values .get_variables lp, row(0) For j = 1 To Ncol Debug.Print .get_col_name(lp, j) & ": " & row(j - 1) Next ' we are done now End If ' free allocated memory Erase row Erase colno If lp <> 0 Then ' clean up such that all used memory by lpsolve is freed .delete_lp lp End If Demo = ret End With End Function
When this is run, the following is shown in the debug window:
Objective value: 6315.625 x: 21.875 y: 53.125
And a file model.lp is created with the following contents:
/* Objective function */ max: +143 x +60 y; /* Constraints */ +120 x +210 y <= 15000; +110 x +30 y <= 4000; +x +y <= 75;
Note that a class lpsolve55.cls or the lpsolve55 COM object is needed for this to work. The class is available via the VB example and the COM object is also available.
Note that this example is very limited. It is also possible to set bounds on variables, ranges on constraints, define variables as integer, get more result information, changing solver options and parameters and much more. See lp_solve API reference for an overview of the API to do this.
The example model can be formulated as follows in VB.NET:
Option Strict Off Option Explicit On Module Module1 'demo Private lpsolve As lpsolve55 Public Sub Main() lpsolve = New lpsolve55 lpsolve.Init(".") Demo() lpsolve = Nothing End Sub Private Function Demo() As Integer Dim lp As Integer Dim Ncol As Integer Dim colno() As Integer Dim j, ret As Short Dim row() As Double With lpsolve ' We will build the model row by row ' So we start with creating a model with 0 rows and 2 columns Ncol = 2 ' there are two variables in the model lp = .make_lp(0, Ncol) If lp = 0 Then ret = 1 ' couldn't construct a new model... End If If ret = 0 Then ' let us name our variables. Not required, but can be useful for debugging .set_col_name(lp, 1, "x") .set_col_name(lp, 2, "y") ' create space large enough for one row ReDim colno(Ncol - 1) ReDim row(Ncol - 1) End If If ret = 0 Then .set_add_rowmode(lp, True) ' makes building the model faster if it is done rows by row ' construct first row (120 x + 210 y <= 15000) j = 0 colno(j) = 1 ' first column row(j) = 120 j = j + 1 colno(j) = 2 ' second column row(j) = 210 j = j + 1 ' add the row to lpsolve If .add_constraintex(lp, j, row(0), colno(0), lpsolve55.lpsolve_constr_types.LE, 15000) = False Then ret = 3 End If End If If ret = 0 Then ' construct second row (110 x + 30 y <= 4000) j = 0 colno(j) = 1 ' first column row(j) = 110 j = j + 1 colno(j) = 2 ' second column row(j) = 30 j = j + 1 ' add the row to lpsolve If .add_constraintex(lp, j, row(0), colno(0), lpsolve55.lpsolve_constr_types.LE, 4000) = False Then ret = 3 End If End If If ret = 0 Then ' construct third row (x + y <= 75) j = 0 colno(j) = 1 ' first column row(j) = 1 j = j + 1 colno(j) = 2 ' second column row(j) = 1 j = j + 1 ' add the row to lpsolve If .add_constraintex(lp, j, row(0), colno(0), lpsolve55.lpsolve_constr_types.LE, 75) = False Then ret = 3 End If End If If ret = 0 Then .set_add_rowmode(lp, False) ' rowmode should be turned off again when done building the model ' set the objective function (143 x + 60 y) j = 0 colno(j) = 1 ' first column row(j) = 143 j = j + 1 colno(j) = 2 ' second column row(j) = 60 j = j + 1 ' set the objective in lpsolve If .set_obj_fnex(lp, j, row(0), colno(0)) = False Then ret = 4 End If End If If ret = 0 Then ' set the object direction to maximize .set_maxim(lp) ' just out of curioucity, now show the model in lp format on screen ' this only works if this is a console application. If not, use write_lp and a filename .write_lp(lp, "model.lp") ' I only want to see important messages on screen while solving .set_verbose(lp, 3) ' Now let lpsolve calculate a solution ret = .solve(lp) If ret = lpsolve55.lpsolve_return.OPTIMAL Then ret = 0 Else ret = 5 End If End If If ret = 0 Then ' a solution is calculated, now lets get some results ' objective value System.Diagnostics.Debug.WriteLine("Objective value: " & .get_objective(lp)) ' variable values .get_variables(lp, row(0)) For j = 1 To Ncol System.Diagnostics.Debug.WriteLine(.get_col_name(lp, j) & ": " & row(j - 1)) Next ' we are done now End If ' free allocated memory Erase row Erase colno If lp <> 0 Then ' clean up such that all used memory by lpsolve is freed .delete_lp(lp) End If Demo = ret End With End Function End Module
When this is run, the following is shown in the debug window:
Objective value: 6315.625 x: 21.875 y: 53.125
And a file model.lp is created with the following contents:
/* Objective function */ max: +143 x +60 y; /* Constraints */ +120 x +210 y <= 15000; +110 x +30 y <= 4000; +x +y <= 75;
Note that a class lpsolve55.vb is needed for this to work. The class is available via the VB.NET example.
Note that this example is very limited. It is also possible to set bounds on variables, ranges on constraints, define variables as integer, get more result information, changing solver options and parameters and much more. See lp_solve API reference for an overview of the API to do this.
The example model can be formulated as follows in C#.NET:
using System.Windows.Forms; using lpsolve55; /* demo.cs */ namespace demo { public class demo { public static void Main() { lpsolve.Init("."); Demo(); } private static int Demo() { int lp; int Ncol; int[] colno; int j, ret = 0; double[] row; /* We will build the model row by row */ /* So we start with creating a model with 0 rows and 2 columns */ Ncol = 2; /* there are two variables in the model */ lp = lpsolve.make_lp(0, Ncol); if (lp == 0) ret = 1; /* couldn't construct a new model... */ if (ret == 0) { /* let us name our variables. Not required, but can be useful for debugging */ lpsolve.set_col_name(lp, 1, "x"); lpsolve.set_col_name(lp, 2, "y"); } /* create space large enough for one row */ colno = new int[Ncol]; row = new double[Ncol]; if (ret == 0) { lpsolve.set_add_rowmode(lp, true); /* makes building the model faster if it is done rows by row */ /* construct first row (120 x + 210 y <= 15000) */ j = 0; colno[j] = 1; /* first column */ row[j++] = 120; colno[j] = 2; /* second column */ row[j++] = 210; /* add the row to lpsolve */ if (lpsolve.add_constraintex(lp, j, ref row[0], ref colno[0], lpsolve.lpsolve_constr_types.LE, 15000) == false) ret = 3; } if (ret == 0) { /* construct second row (110 x + 30 y <= 4000) */ j = 0; colno[j] = 1; /* first column */ row[j++] = 110; colno[j] = 2; /* second column */ row[j++] = 30; /* add the row to lpsolve */ if (lpsolve.add_constraintex(lp, j, ref row[0], ref colno[0], lpsolve.lpsolve_constr_types.LE, 4000) == false) ret = 3; } if (ret == 0) { /* construct third row (x + y <= 75) */ j = 0; colno[j] = 1; /* first column */ row[j++] = 1; colno[j] = 2; /* second column */ row[j++] = 1; /* add the row to lpsolve */ if (lpsolve.add_constraintex(lp, j, ref row[0], ref colno[0], lpsolve.lpsolve_constr_types.LE, 75) == false) ret = 3; } if (ret == 0) { lpsolve.set_add_rowmode(lp, false); /* rowmode should be turned off again when done building the model */ /* set the objective function (143 x + 60 y) */ j = 0; colno[j] = 1; /* first column */ row[j++] = 143; colno[j] = 2; /* second column */ row[j++] = 60; /* set the objective in lpsolve */ if (lpsolve.set_obj_fnex(lp, j, ref row[0], ref colno[0]) == false) ret = 4; } if (ret == 0) { lpsolve.lpsolve_return s; /* set the object direction to maximize */ lpsolve.set_maxim(lp); /* just out of curioucity, now show the model in lp format on screen */ /* this only works if this is a console application. If not, use write_lp and a filename */ lpsolve.write_lp(lp, "model.lp"); /* I only want to see important messages on screen while solving */ lpsolve.set_verbose(lp, 3); /* Now let lpsolve calculate a solution */ s = lpsolve.solve(lp); if (s == lpsolve.lpsolve_return.OPTIMAL) ret = 0; else ret = 5; } if (ret == 0) { /* a solution is calculated, now lets get some results */ /* objective value */ System.Diagnostics.Debug.WriteLine("Objective value: " + lpsolve.get_objective(lp)); /* variable values */ lpsolve.get_variables(lp, ref row[0]); for(j = 0; j < Ncol; j++) System.Diagnostics.Debug.WriteLine(lpsolve.get_col_name(lp, j + 1) + ": " + row[j]); /* we are done now */ } /* free allocated memory */ if (lp != 0) { /* clean up such that all used memory by lpsolve is freed */ lpsolve.delete_lp(lp); } return(ret); } //Demo } }
When this is run, the following is shown in the debug window:
Objective value: 6315.625 x: 21.875 y: 53.125
And a file model.lp is created with the following contents:
/* Objective function */ max: +143 x +60 y; /* Constraints */ +120 x +210 y <= 15000; +110 x +30 y <= 4000; +x +y <= 75;
Note that a class lpsolve55.cs is needed for this to work. The class is available via the CS.NET example.
Note that this example is very limited. It is also possible to set bounds on variables, ranges on constraints, define variables as integer, get more result information, changing solver options and parameters and much more. See lp_solve API reference for an overview of the API to do this.
docs/5.5/quickstart.htm 0000644 0001750 0001750 00000021266 11306036626 013677 0 ustar rene rene
Quick Startlp_solve (or lpsolve) has allot of features in-house. For a beginner, it can be difficult to determine where to start. The distribution contains many files and to start with, you need only a couple of them. As you learn the package you may need extras. This text explains how to start with lp_solve. Skip the blabla, just give me a very quick start.How to call lp_solveBasically, lp_solve is a library, a set of routines, called the API that can be called from almost any programming language to solve MILP problems. There are several ways to pass the data to the library:
Via the APIThe API is a set of routines that can be called from a programming language to build the model in memory, solve it and return the results. There are many API routines to perform many possible tasks and set several options. See lp_solve API reference for an overview.Via input filesStandard, lp_solve supports several input files types.
The common known MPS format (see mps-format) is supported by most solvers, but
it is not very readable for humans. Another format is the lp format (see lp-format)
that is more readable. lp_solve has the unique ability to use user-written routines to input the model
(see External Language Interface).
See read_mps, read_freemps, read_MPS, read_freeMPS and read_lp, read_LP for
the API calls to read the model from file. Via an IDEThanks to Henri Gourvest, there is now also an IDE program called LPSolve IDE that uses the API to provide a Windows application to solve models. See LPSolve IDE for its usage. With this program you don't have to know anything of API or computer programming languages. You can just provide your model to the program and it will solve the model and give you the result. As already stated, lp_solve can be called from many programming language. Among them are C, C++, Pascal, Delphi, Java, VB, C#, VB.NET, Excel. But let this list not be a limitation. Any programming language capable of calling external libraries (DLLs under Windows, Shared libraries (.so) under Unix/Linux) can call lp_solve. Some key features of lp_solve
Quick quick startFormulating a problemIf you don't know much about linear programming, first take a look at Formulation of an lp problem in lpsolve. Start with reading the first part where a practical example is presented until the point where the formulation is given in mathematical format, then return to here. This practical example is used in the next presentations. Solve a problem via the IDEThe easiest way to start with lp_solve is via the IDE. This only works under Windows. See LPSolve IDE. Solve a problem via the lp_solve command line programAnother way to solve a model is via the lp_solve command line program. This works on any platform, but is completely command-line driven. Well known by Unix/Linux shell programmers and DOS box users. See lp_solve command. solve a problem via the APIProgrammers want to call lp_solve in a totally different way. They want to call lp_solve as a library directly from their programming language. This is what is called the API (Application Programming Interface). See Calling the lpsolve API from your application and Construct the model from a Programming Language. An overview of the complete API can be found on: lp_solve API reference. Compile the source code yourselfThe distribution contains precompiled libraries/binaries for Windows and Linux. However lp_solve can be compiled on other platforms also. You may also to make modifications to it and then you have to recompile also, even on the precompiled platforms. See Calling the lpsolve API from your application. In this article it is both explained how to link your code to the library and how to compile the lp_solve code. Basis Factorization PackagesAlternative inverse/re-factorization libraries can be used by lp_solve. This is a feature for the more experienced users of lp_solve. See Basis Factorization Packages for more information. The sources of these packages are in the lp_solve_5.5.0.13_bfp_*_source.tar.gz archives. The binaries are in the lp_solve_5.5.0.13_exe* archive. External Language InterfacesAlternative model readers and writers possible via the XLI implementation. Models expressed in format files other than lp or MPS format can also be read or written by lp_solve via this unique feature. See External Language Interfaces for more information. The sources of these packages are in the lp_solve_5.5.0.13_xli_*_source.tar.gz archives. The binaries are in the lp_solve_5.5.0.13_exe* archive. Calling lp_solve from higher level Mathematical languages.lp_solve can be called from AMPL, MATLAB, O-Matrix, Scilab, Octave, Python, R.You now have a pretty good idea what lp_solve is about. |
get_objectiveReturns the value of the objective function. REAL get_objective(lprec *lp); Return Value get_objective returns the value of the objective. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The get_objective function returns the value of the objective of the last
solve. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, is_feasible, get_variables, get_ptr_variables, get_working_objective, get_constraints, get_ptr_constraints, get_constr_value, get_primal_solution, get_ptr_primal_solution, get_var_primalresult, get_sensitivity_rhs, get_ptr_sensitivity_rhs, get_dual_solution, get_ptr_dual_solution, get_var_dualresult, get_sensitivity_obj, get_ptr_sensitivity_obj, get_sensitivity_objex, get_ptr_sensitivity_objex |
is_obj_in_basisReturns if the objective is in the matrix or not. unsigned char is_obj_in_basis(lprec *lp); Return Value is_obj_in_basis returns if the objective is in the matrix or not. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The is_obj_in_basis function returns if the objective is in the matrix or not. By default, the objective function is stored as the top row in the constraint matrix When this function is called with obj_in_basis = FALSE then it is moved out into separate storage. When out of the basis, the computation of reduced costs is somewhat slower. In the late versions of v5.5, there is now the option to calculate reduced cost in the textbook way, i.e. completely independently of the basis. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_obj_in_basis |
get_presolveReturns if a presolve must be done before solving. int get_presolve(lprec *lp); Return Value get_presolve returns the current presolve setting. Can by the combination (OR) of any of the following values:
Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The get_presolve function returns if a presolve must be done before
solving. Presolve looks at the model and tries to simplify it so that solving
times are shorter. For example a constraint on only one variable is converted
to a bound on this variable (and the constraint is deleted). Note that the
model dimensions can change because of this, so be careful with this. Both rows
and columns can be deleted by the presolve. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_presolveloops, set_presolve, is_presolve |
set_epslevelThis is a simplified way of specifying multiple eps thresholds that are "logically" consistent. unsigned char set_epslevel(lprec *lp, int epslevel); Return Value Returns TRUE if level accepted and FALSE if an incalid epsilon level was provided. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI epslevel Can by any of the following values:
Remarks This is a simplified way of specifying multiple eps thresholds that are "logically" consistent. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_epsel, set_epsb, set_epsd, set_epspivot, set_epsint, set_mip_gap |
Developed at INRIA, Scilab has been developed for system control and signal processing applications. It is freely distributed in source code format.
Scilab is made of three distinct parts: an interpreter, libraries of functions (Scilab procedures) and libraries of Fortran and C routines. These routines (which, strictly speaking, do not belong to Scilab but are interactively called by the interpreter) are of independent interest and most of them are available through Netlib. A few of them have been slightly modified for better compatibility with Scilab's interpreter. A key feature of the Scilab syntax is its ability to handle matrices: basic matrix manipulations such as concatenation, extraction or transpose are immediately performed as well as basic operations such as addition or multiplication. Scilab also aims at handling more complex objects than numerical matrices. For instance, control people may want to manipulate rational or polynomial transfer matrices. This is done in Scilab by manipulating lists and typed lists which allows a natural symbolic representation of complicated mathematical objects such as transfer functions, linear systems or graphs.
Polynomials, polynomials matrices and transfer matrices are also defined and the syntax used for manipulating these matrices is identical to that used for manipulating constant vectors and matrices.
Scilab provides a variety of powerful primitives for the analysis of non-linear systems. Integration of explicit and implicit dynamic systems can be accomplished numerically. The scicos toolbox allows the graphic definition and simulation of complex interconnected hybrid systems.
Scilab has an open programming environment where the creation of functions and libraries of functions is completely in the hands of the user. Functions are recognized as data objects in Scilab and, thus, can be manipulated or created as other data objects. For example, functions can be defined inside Scilab and passed as input or output arguments of other functions.
In addition Scilab supports a character string data type which, in particular, allows the on-line creation of functions. Matrices of character strings are also manipulated with the same syntax as ordinary matrices.
Finally, Scilab is easily interfaced with Fortran or C subprograms. This allows use of standardized packages and libraries in the interpreted environment of Scilab.
The general philosophy of Scilab is to provide the following sort of computing environment:
We will not discuss the specifics of Scilab here but instead refer the reader to the Scilab website and documentation.
lpsolve is callable from Scilab via an external interface. As such, it looks like lpsolve is fully integrated with Scilab. Matrices can directly be transferred between Scilab and lpsolve in both directions. The complete interface is written in C so it has maximum performance. The whole lpsolve API is implemented with some extra's specific for Scilab (especially for matrix support). So you have full control to the complete lpsolve functionality via the sclpsolve Scilab driver. If you find that this involves too much work to solve an lp model then you can also work via higher-level scripts that can make things a lot easier. See further in this article.
Compile and build sclpsolve: ---------------------------- 1. Get the needed sources and libraries: Archive lp_solve_5.5.0.13_scilab_source.tar.gz contains the sources to build sclpsolve. Uncompress it to a directory, for example d:\lp_solve. Make sure that the folder structure is kept. It will create a directory structure lp_solve_5.5\extra\scilab\lpsolve in that folder. Archive lp_solve_5.5.0.13_dev.zip (Windows) or lp_solve_5.5.0.13_dev.tar.gz (Unix) contains needed libraries and include files to link the sources with. Uncompress it to the same folder as for the sources, appended with lp_solve_5.5. In this example that would be d:\lp_solve\lp_solve_5.5 You have now all needed files in place. In your chosen directory (in this example d:\lp_solve) there will only be a directory lp_solve_5.5 In this directory, you have a directory extra and some files ending with .h and .lib The extra directory contains a scilab directory which contains a directory lpsolve with some files and directories. 2. Under Windows, the Microsoft Visual C/C++ compiler must be installed and the environment variables must be active so that when a command prompt is opened, the cl and nmake commands can be executed. This can be done also by opening a command prompt and execute the batch file VCVARS32.BAT (somewhere on your system) and then starting scilab from that same command prompt. Under Unix/Linux, the standard c compiler is used so no special things must be done. 3. Edit the file Path.incl (under lp_solve_5.5\extra\scilab\lpsolve) and change pathnames as needed: SCIDIR and SCIDIR1: two times the folder where scilab is installed. For example F:\Program Files\scilab-4.1.2 LPSOLVEDIR and LPSOLVELIBDIR: the folder where you uncompressed the scilab source archive into appened with \lp_solve_5.5. In this example d:\lp_solve\lp_solve_5.5 4. Start Scilab 5. Check under Scilab that the current directory is the lpsolve directory. Use the Scilab pwd command to show the current directory. With the chdir command, you can change the current directory. This current directory must be lp_solve_5.5/extra/scilab/lpsolve example: chdir('d:/lp_solve/lp_solve_5.5/extra/scilab/lpsolve') 6. To compile and build sclpsolve, enter the following command in Scilab: -->exec builder.sce This should be done once to build the sclpsolve driver and to produce the file loader.sce. Load the sclpsolve driver in the Scilab memory space: ----------------------------------------------------- 1. Under Windows, make sure that the lpsolve55.dll file is somewhere in the path Under Unix/Linux, make sure that the liblpsolve55.so shared library is in /usr/lib or /lib so that Unix can find it. They are in archives lp_solve_5.5.0.13_dev.zip/lp_solve_5.5.0.13_dev.tar.gz and were installed in the lp_solve_5.5 directory of step 1 of the previous procedure. 2. It is required that the sclpsolve driver is first build. That must be done only once. So if you haven't taken the steps yet to build the sclpsolve driver, then do this first as described previously in 'Compile and build sclpsolve' 3. Start Scilab 4. Check under Scilab that the current directory is the lpsolve directory. Use the Scilab pwd command to show the current directory. With the chdir command, you can change the current directory. This current directory must be lp_solve_5.5/extra/scilab/lpsolve example: chdir('/lp_solve/lp_solve_5.5/extra/scilab/lpsolve') 5. Enter the following command in Scilab: -->exec loader.sce
To make this possible, a driver program is needed: sclpsolve (sclpsolve.dll under Windows, sclpsolve.a under Unix/Linux). This driver must be put in a directory known to Scilab and Scilab can call the sclpsolve solver.
This driver calls lpsolve via the lpsolve shared library (lpsolve55.dll under Windows and liblpsolve55.so under Unix/Linux) (in archive lp_solve_5.5.0.13_dev.zip/lp_solve_5.5.0.13_dev.tar.gz). This has the advantage that the sclpsolve driver doesn't have to be recompiled when an update of lpsolve is provided. For Windows, the lpsolve55.dll file must be somewhere in the path. For Unix, the lpsolve shared library (liblpsolve55.so) must be in the /usr/lib or /lib directory.
So note the difference between the Scilab lpsolve driver that is called sclpsolve and the lpsolve library that implements the API that is called lpsolve55.
There are also some Scilab script files (*.sce, *.sci) as a quick start.
The first thing that must be done, each time Scilab is restarted and you want to use lpsolve is load the sclpsolve driver into the Scilab workspace. This can be done via the script loader.sce. The following command must be used to load the driver:
exec loader.sce
It is assumed here that the current directory is the Scilab lpsolve directory (lp_solve_5.5/extra/scilab/lpsolve), but this is not a requirement. You can also provide the full path to the script files. The current directory can be shown via the pwd command in Scilab:
pwd
That is basically all you need to do. From now on, you can use the library. This until Scilab is restarted. Then this command must be given again to reload the library.
To make things easier, you can edit the file scilab.star with your favourite editor (or notepad/vi) in the Scilab directory and add above line at the end of this file. That will automatically load the lpsolve driver in memory when Scilab is started. So it will appear as if the sclpsolve command is then always available.
If you get an error similar to below, then probably the lpsolve library can not be found:
link failed for dll c:\lp_solve\lp_solve_5.5\extra\scilab\lpsolve\libs\sclpsolve.dll addinter(liblpmex,'lpmex_gateway','sclpsolve') !--error 236 link: the shared archive was not loaded
Under Windows, the lpsolve55.dll file must be in one of the directories specified by the PATH environment variable. This path can be seen in Scilab via the command getenv("PATH"). It is common to place dlls in the WINDOWS\system32 folder.
Under Unix/Linux, the liblpsolve55.so file must be in the directory /usr/lib or /lib.
To test if everything is installed correctly, enter sclpsolve() in the Scilab command window. If it gives the following, then everything is ok:
sclpsolve scilab Interface version 5.5.0.5 using lpsolve version 5.5.0.13 Usage: [ret1, ret2, ...] = sclpsolve('functionname', arg1, arg2, ...)
All this is developed and tested with Scilab versions 2.7 and 3.0 both under Windows and Linux (RedHat).
In the following text, --> before the Scilab commands is the Scilab prompt. Only the text after --> must be entered.
To call an lpsolve function, the following syntax must be used:
-->[ret1, ret2, ...] = sclpsolve('functionname', arg1, arg2, ...)
The return values are optional and depend on the function called. functionname must always be enclosed between (single or double) quotes to make it alphanumerical and it is case sensitive. The number and type of arguments depend on the function called. Some functions even have a variable number of arguments and a different behaviour occurs depending on the type of the argument. functionname can be (almost) any of the lpsolve API routines (see lp_solve API reference) plus some extra Scilab specific functions. Most of the lpsolve API routines use or return an lprec structure. To make things more robust in Scilab, this structure is replaced by a handle or the model name. The lprec structures are maintained internally by the lpsolve driver. The handle is an incrementing number starting from 0. Starting from driver version 5.5.0.2, it is also possible to use the model name instead of the handle. This can of course only be done if a name is given to the model. This is done via lpsolve routine set_lp_name or by specifying the model name in routine read_lp. See Using model name instead of handle.
Almost all callable functions can be found in the lp_solve API reference. Some are exactly as described in the reference guide, others have a slightly different syntax to make maximum use of the Scilab functionality. For example make_lp is used identical as described. But get_variables is slightly different. In the API reference, this function has two arguments. The first the lp handle and the second the resulting variables and this array must already be dimensioned. When lpsolve is used from Scilab, nothing must be dimensioned in advance. The sclpsolve driver takes care of dimensioning all return variables and they are always returned as return value of the call to sclpsolve. Never as argument to the routine. This can be a single value as for get_objective (although Scilab stores this in a 1x1 matrix) or a matrix or vector as in get_variables. In this case, get_variables returns a 4x1 matrix (vector) with the result of the 4 variables of the lp model.
Note that you can get an overview of the available functionnames and their arguments by entering the following in Scilab:
-->help sclpsolve
(Note that you can execute this example by entering command per command as shown below or by just entering exec example1.sce. This will execute example1.sce.)
-->lp=sclpsolve('make_lp', 0, 4); -->sclpsolve('set_verbose', lp, 3); -->sclpsolve('set_obj_fn', lp, [1, 3, 6.24, 0.1]); -->sclpsolve('add_constraint', lp, [0, 78.26, 0, 2.9], 2, 92.3); -->sclpsolve('add_constraint', lp, [0.24, 0, 11.31, 0], 1, 14.8); -->sclpsolve('add_constraint', lp, [12.68, 0, 0.08, 0.9], 2, 4); -->sclpsolve('set_lowbo', lp, 1, 28.6); -->sclpsolve('set_lowbo', lp, 4, 18); -->sclpsolve('set_upbo', lp, 4, 48.98); -->sclpsolve('set_col_name', lp, 1, 'COLONE'); -->sclpsolve('set_col_name', lp, 2, 'COLTWO'); -->sclpsolve('set_col_name', lp, 3, 'COLTHREE'); -->sclpsolve('set_col_name', lp, 4, 'COLFOUR'); -->sclpsolve('set_row_name', lp, 1, 'THISROW'); -->sclpsolve('set_row_name', lp, 2, 'THATROW'); -->sclpsolve('set_row_name', lp, 3, 'LASTROW'); -->sclpsolve('write_lp', lp, 'a.lp'); -->sclpsolve('get_mat', lp, 1, 2) ans = 78.26 -->sclpsolve('solve', lp) ans = 0. -->sclpsolve('get_objective', lp) ans = 31.782759 -->sclpsolve('get_variables', lp) ans = ! 28.6 ! ! 0. ! ! 0. ! ! 31.827586 ! -->sclpsolve('get_constraints', lp) ans = ! 92.3 ! ! 6.864 ! ! 391.29283 !
Note that there are some commands that return an answer. To see the answer, the command was not terminated with a semicolon (;). If the semicolon is put at the end of a command, the answer is not shown. However it is also possible to write the answer in a variable. For example:
-->obj=sclpsolve('get_objective', lp) obj = 31.782759
Or without echoing on screen:
-->obj=sclpsolve('get_objective', lp);
The last command will only write the result in variable obj without showing anything on screen. get_variables and get_constraints return a vector with the result. This can also be put in a variable:
-->x=sclpsolve('get_variables', lp); -->b=sclpsolve('get_constraints', lp);
It is always possible to show the contents of a variable by just giving it as command:
-->x x = ! 28.6 ! ! 0. ! ! 0. ! ! 31.827586 !
Don't forget to free the handle and its associated memory when you are done:
-->sclpsolve('delete_lp', lp);
-->lp=sclpsolve('make_lp', 0, 4); -->sclpsolve('set_lp_name', lp, 'mymodel'); -->sclpsolve('set_verbose', 'mymodel', 3); -->sclpsolve('set_obj_fn', 'mymodel', [1, 3, 6.24, 0.1]); -->sclpsolve('add_constraint', 'mymodel', [0, 78.26, 0, 2.9], 2, 92.3); -->sclpsolve('add_constraint', 'mymodel', [0.24, 0, 11.31, 0], 1, 14.8); -->sclpsolve('add_constraint', 'mymodel', [12.68, 0, 0.08, 0.9], 2, 4); -->sclpsolve('set_lowbo', 'mymodel', 1, 28.6); -->sclpsolve('set_lowbo', 'mymodel', 4, 18); -->sclpsolve('set_upbo', 'mymodel', 4, 48.98); -->sclpsolve('set_col_name', 'mymodel', 1, 'COLONE'); -->sclpsolve('set_col_name', 'mymodel', 2, 'COLTWO'); -->sclpsolve('set_col_name', 'mymodel', 3, 'COLTHREE'); -->sclpsolve('set_col_name', 'mymodel', 4, 'COLFOUR'); -->sclpsolve('set_row_name', 'mymodel', 1, 'THISROW'); -->sclpsolve('set_row_name', 'mymodel', 2, 'THATROW'); -->sclpsolve('set_row_name', 'mymodel', 3, 'LASTROW'); -->sclpsolve('write_lp', 'mymodel', 'a.lp'); -->sclpsolve('get_mat', 'mymodel', 1, 2) ans = 78.26 -->sclpsolve('solve', 'mymodel') ans = 0. -->sclpsolve('get_objective', 'mymodel') ans = 31.782759 -->sclpsolve('get_variables', 'mymodel') ans = ! 28.6 ! ! 0. ! ! 0. ! ! 31.827586 ! -->sclpsolve('get_constraints', 'mymodel') ans = ! 92.3 ! ! 6.864 ! ! 391.29283 !
So everywhere a handle is needed, you can also use the model name. You can even mix the two methods.
There is also a specific Scilab routine to get the handle from the model name: get_handle.
For example:
-->sclpsolve('get_handle', 'mymodel') 0
Don't forget to free the handle and its associated memory when you are done:
-->sclpsolve('delete_lp', 'mymodel');
In the next part of this documentation, the handle is used. But if you name the model, the name could thus also be used.
-->sclpsolve('add_constraint', lp, [0.24, 0, 11.31, 0], 1, 14.8);
In sparse matrix notation, this can be written:
-->sclpsolve('add_constraint', lp, mtlb_sparse(sparse([0.24, 0, 11.31, 0])), 1, 14.8);
Most of the time, variables are used to provide the data:
-->sclpsolve('add_constraint', lp, a1, 1, 14.8);
Where a1 is a dense matrix variable. A sparse matrix is then provided as follows:
-->sclpsolve('add_constraint', lp, mtlb_sparse(a1), 1, 14.8);
The sclpsolve driver sees all provided matrices as sparse matrices. sclpsolve also uses sparse matrices internally and data can be provided sparse via the ex routines. For example add_constraintex. The sclpsolve driver always uses the ex routines to provide the data to lpsolve. Even if you call from Scilab the routine names that would require a dense matrix (for example add_constraint), the sclpsolve driver will always call the sparse version of the routine (for example add_constraintex). This results in the most performing behaviour. Note that if a dense matrix is provided, the dimension must exactly match the dimension that is expected by sclpsolve. Matrices with too few or too much elements gives an 'invalid vector.' error. Sparse matrices can off course provide less elements (the non provided elements are seen as zero). However if too many elements are provided or an element with a too large index, again an 'invalid vector.' error is raised.
Most of the time, sclpsolve needs vectors (rows or columns). In all situations, it doesn't matter if the vectors are row or column vectors. The driver accepts them both. For example:
-->sclpsolve('add_constraint', lp, [0.24; 0; 11.31; 0], 1, 14.8);
Which is a column vector, but it is also accepted.
An important final note. Several lp_solve API routines accept a vector where the first element (element 0) is not used. Other lp_solve API calls do use the first element. In the Scilab interface, there is never an unused element in the matrices. So if the lp_solve API specifies that the first element is not used, then this element is not in the Scilab matrix.
All numerical data is stored in matrices. Alphanumerical data, however, is more difficult to store in matrices. Matrices require that each element has the same size (length) and that is difficult and unpractical for alphanumerical data. In a limited number of lpsolve routines, alphanumerical data is required or returned and in some also multiple elements. An example is set_col_name. For this, Scilab sets are used. To specify a set of alphanumerical elements, the following notation is used: { 'element1', 'element2', ... }. Note the { and } symbols instead of [ and ] that are used with matrices.
It is noted however that this doesn't seem to work very well in Scilab. Scilab allows to return string sets, but when a string set is provided to an interface program, the following error occurs:
!--error 9999 Invalid string matrix (at most one column!) !--error 999 SIGSTP: aborting current computation
This is not an error generated by the sclpsolve driver, but from the Scilab parser. Hopefully, this problem will be corrected in the future.
Because Scilab is all about matrices, all lpsolve API routines that need a column or row number to get/set information for that
column/row are extended in the sclpsolve Scilab driver to also work with matrices. For example set_int in the API can
only set the integer status for one column. If the status for several integer variables must be set, then set_int
must be called multiple times. The sclpsolve Scilab driver however also allows specifying a vector to set the integer
status of all variables at once. The API call is: return = sclpsolve('set_int', lp, column, must_be_int). The
matrix version of this call is: return = sclpsolve('set_int', lp, [must_be_int]).
The API call to return the integer status of a variable is: return = sclpsolve('is_int', lp, column). The
matrix version of this call is: [is_int] = sclpsolve('is_int', lp)
Also note the get_mat and set_mat routines. In Scilab these are extended to return/set the complete constraint matrix.
See following example.
Above example can thus also be done as follows:
(Note that you can execute this example by entering command per command as shown below or by just entering exec example2.sce.
This will execute example2.sce.)
-->lp=sclpsolve('make_lp', 0, 4); -->sclpsolve('set_verbose', lp, 3); -->sclpsolve('set_obj_fn', lp, [1, 3, 6.24, 0.1]); -->sclpsolve('add_constraint', lp, [0, 78.26, 0, 2.9], 2, 92.3); -->sclpsolve('add_constraint', lp, [0.24, 0, 11.31, 0], 1, 14.8); -->sclpsolve('add_constraint', lp, [12.68, 0, 0.08, 0.9], 2, 4); -->sclpsolve('set_lowbo', lp, [28.6, 0, 0, 18]); -->sclpsolve('set_upbo', lp, [%inf, %inf, %inf, 48.98]); -->// gives a Scilab error with most releases :-( -->// sclpsolve('set_col_name', lp, {'COLONE','COLTWO','COLTHREE','COLFOUR'}); -->// sclpsolve('set_row_name', lp, {'THISROW','THATROW','LASTROW'}); -->sclpsolve('write_lp', lp, 'a.lp'); -->sclpsolve('get_mat', lp) ans = ! 0. 78.26 0. 2.9 ! ! .24 0. 11.31 0. ! ! 12.68 0. .08 .9 ! -->sclpsolve('solve', lp) ans = 0. -->sclpsolve('get_objective', lp) ans = 31.782759 -->sclpsolve('get_variables', lp) ans = ! 28.6 ! ! 0. ! ! 0. ! ! 31.827586 ! -->sclpsolve('get_constraints', lp) ans = ! 92.3 ! ! 6.864 ! ! 391.29283 !
Note the usage of %inf in set_upbo. This stands for 'infinity'. Meaning an infinite upper bound. It is also possible to use -%inf to express minus infinity. This can for example be used to create a free variable.
Starting from driver version 5.5.0.3, get_mat can also return the matrix in sparse format. By default the function returns it in dense format for backwards compatibility. However if a 3rd argument is provided that is non-zero, the returned matrix is sparse:
-->sclpsolve('get_mat', lp, 1) ans = (3, 4) m sparse matrix (2, 1) .24 (3, 1) 12.68 (1, 2) 78.26 (2, 3) 11.31 (3, 3) .08 (1, 4) 2.9 (3, 4) .9
To show the full power of the matrices, let's now do some matrix calculations to check the solution. It works further on above example:
-->A=sclpsolve('get_mat', lp); -->X=sclpsolve('get_variables', lp); -->B = A * X B = ! 92.3 ! ! 6.864 ! ! 391.29283 !
So what we have done here is calculate the values of the constraints (RHS) by multiplying the constraint matrix with the solution vector. Now take a look at the values of the constraints that lpsolve has found:
-->sclpsolve('get_constraints', lp) ans = ! 92.3 ! ! 6.864 ! ! 391.29283 !
Exactly the same as the calculated B vector, as expected.
Also the value of the objective can be calculated in a same way:
-->C=sclpsolve('get_obj_fn', lp); -->X=sclpsolve('get_variables', lp); obj = 31.782759
So what we have done here is calculate the value of the objective by multiplying the objective vector with the solution vector. Now take a look at the value of the objective that lpsolve has found:
-->sclpsolve('get_objective', lp) ans = 31.7828
Again exactly the same as the calculated obj value, as expected.
Scilab can execute a sequence of statements stored in diskfiles. Scilab has two kinds of these. The first kinds are ASCII files where Scilab commands are written in the same way as in the command window. These files normally have the extension .sce. These script files must be executed via the exec command. For example:
exec example1.sce
The second kinds are binary files. However the user enters the commands first in an ASCII file (normally with extension .sci) and then these are translated to binary files via the Scilab genlib command. The .sci files also may only contain Scilab commands. There are two advantages of using these. The first is that you don't have to use the exec command or provide the extension to execute them. So it is as if you execute a regular Scilab command. The second advantage is that they are somewhat faster.
The lpsolve distribution contains some sample .sce files that must be executed via exec and also some .sci high-level routines that can be executed without exec. They are already precompiled.
Contains the commands as shown in the first example of this article. Execute via exec example1.sce
Contains the commands as shown in the second example of this article. Execute via exec example2.sce
Contains the commands of a practical example. See further in this article.
Contains the commands of a practical example. See further in this article.
Contains the commands of a practical example. See further in this article.
Contains the commands of a practical example. See further in this article.
This script uses the API to create a higher-level function called lp_solve. This function accepts as arguments some matrices and options to create and solve an lp model. See the beginning of the file or type help lp_solve to see its usage:
LP_SOLVE Solves mixed integer linear programming problems. SYNOPSIS: [obj,x,duals] = lp_solve(f,a,b,e,vlb,vub,xint,scalemode,keep) solves the MILP problem max v = f'*x a*x <> b vlb <= x <= vub x(int) are integer ARGUMENTS: The first four arguments are required: f: n vector of coefficients for a linear objective function. a: m by n matrix representing linear constraints. b: m vector of right sides for the inequality constraints. e: m vector that determines the sense of the inequalities: e(i) = -1 ==> Less Than e(i) = 0 ==> Equals e(i) = 1 ==> Greater Than vlb: n vector of lower bounds. If empty or omitted, then the lower bounds are set to zero. vub: n vector of upper bounds. May be omitted or empty. xint: vector of integer variables. May be omitted or empty. scalemode: scale flag. Off when 0 or omitted. keep: Flag for keeping the lp problem after it's been solved. If omitted, the lp will be deleted when solved. OUTPUT: A nonempty output is returned if a solution is found: obj: Optimal value of the objective function. x: Optimal value of the decision variables. duals: solution of the dual problem.
Example of usage. To create and solve following lp-model:
max: -x1 + 2 x2; C1: 2x1 + x2 < 5; -4 x1 + 4 x2 <5; int x2,x1;
The following command can be used:
-->[obj, x]=lp_solve([-1, 2], [2, 1; -4, 4], [5, 5], [-1, -1], [], [], [1, 2]) x = ! 1. ! ! 2. ! obj = 3.
Note that you can also provide sparse matrices to this function without having to use mtlb_sparse. The script is taking care of this.
This script is analog to the lp_solve script and also uses the API to create a higher-level function called lp_maker. This function accepts as arguments some matrices and options to create an lp model. Note that this scripts only creates a model and returns a handle. See the beginning of the file or type help lp_maker or just lp_maker to see its usage:
-->help lp_maker LP_MAKER Makes mixed integer linear programming problems. SYNOPSIS: lp_handle = lp_maker(f,a,b,e,vlb,vub,xint,scalemode,setminim) make the MILP problem max v = f'*x a*x <> b x >= vlb >= 0 x <= vub x(int) are integer ARGUMENTS: The first four arguments are required: f: n vector of coefficients for a linear objective function. a: m by n matrix representing linear constraints. b: m vector of right sides for the inequality constraints. e: m vector that determines the sense of the inequalities: e(i) < 0 ==> Less Than e(i) = 0 ==> Equals e(i) > 0 ==> Greater Than vlb: n vector of non-negative lower bounds. If empty or omitted, then the lower bounds are set to zero. vub: n vector of upper bounds. May be omitted or empty. xint: vector of integer variables. May be omitted or empty. scalemode: scale flag. Off when 0 or omitted. setminim: Set maximum lp when this flag equals 0 or omitted. OUTPUT: lp_handle is an integer handle to the lp created.
Example of usage. To create following lp-model:
max: -x1 + 2 x2; C1: 2x1 + x2 < 5; -4 x1 + 4 x2 <5; int x2,x1;
The following command can be used:
-->lp=lp_maker([-1, 2], [2, 1; -4, 4], [5, 5], [-1, -1], [], [], [1, 2]) lp = 0.
To solve the model and get the solution:
-->sclpsolve('solve', lp) ans = 0. -->sclpsolve('get_objective', lp) ans = 3. -->sclpsolve('get_variables', lp) ans = ! 1. ! ! 2. !
Don't forget to free the handle and its associated memory when you are done:
-->sclpsolve('delete_lp', lp);
Note that you can also provide sparse matrices to this function without having to use mtlb_sparse. The script is taking care of this.
Contains several examples to build and solve lp models. Execute via exec lpdemo.sce
Contains several examples to build and solve lp models. Also solves the lp_examples from the lp_solve distribution. Execute via exec ex.sce
We shall illustrate the method of linear programming by means of a simple example, giving a combination graphical/numerical solution, and then solve both a slightly as well as a substantially more complicated problem.
Suppose a farmer has 75 acres on which to plant two crops: wheat and barley. To produce these crops, it costs the farmer (for seed, fertilizer, etc.) $120 per acre for the wheat and $210 per acre for the barley. The farmer has $15000 available for expenses. But after the harvest, the farmer must store the crops while awaiting favourable market conditions. The farmer has storage space for 4000 bushels. Each acre yields an average of 110 bushels of wheat or 30 bushels of barley. If the net profit per bushel of wheat (after all expenses have been subtracted) is $1.30 and for barley is $2.00, how should the farmer plant the 75 acres to maximize profit?
We begin by formulating the problem mathematically. First we express the objective, that is the profit, and the constraints algebraically, then we graph them, and lastly we arrive at the solution by graphical inspection and a minor arithmetic calculation.
Let x denote the number of acres allotted to wheat and y the number of acres allotted to barley. Then the expression to be maximized, that is the profit, is clearly
P = (110)(1.30)x + (30)(2.00)y = 143x + 60y.
There are three constraint inequalities, specified by the limits on expenses, storage and acreage. They are respectively:
120x + 210y <= 15000
110x + 30y <= 4000
x + y <= 75
Strictly speaking there are two more constraint inequalities forced by the fact that the farmer cannot plant a negative number of acres, namely:
x >= 0, y >= 0.
Next we graph the regions specified by the constraints. The last two say that we only need to consider the first quadrant in the x-y plane. Here's a graph delineating the triangular region in the first quadrant determined by the first inequality.
-->clear -->X = 0.1:0.1:125; -->Y1 = (15000. - 120*X)/210; -->plot2d3(X, Y1)
Now let's put in the other two constraint inequalities.
-->clear -->X = 0.1:0.05:38; -->Y1 = (15000. - 120*X)/210; -->Y2 = max((4000 - 110.*X)./30, 0); -->Y3 = max(75 - X, 0.); -->Ytop = min(min(Y1, Y2), Y3); -->plot2d3(X, Ytop) -->xtitle("Solution space")
The black area is the solution space that holds valid solutions. This means that any point in this area fulfils the constraints.
Now let's superimpose on top of this picture the objective function P.
-->X = 15:20:35; -->plot2d(X, (6315.63 - 143.0 * X) / 60.0) -->xtitle("Solution space and objective")
The line gives a picture of the objective function. All solutions that intersect with the black area are valid solutions, meaning that this result also fulfils the set constraints. The more the line goes to the right, the higher the objective value is. The optimal solution or best objective is a line that is still in the black area, but with an as large as possible value (as shown here).
It seems apparent that the maximum value of P will occur on the level curve (that is, level
line) that passes through the vertex of the polygon that lies near (22,53).
It is the intersection of x + y = 75 and 110*x + 30*y = 4000
This is a corner point of the diagram. This is not a coincidence. The simplex algorithm, which is used
by lp_solve, starts from a theorem that the optimal solution is such a corner point.
In fact we can compute the result:
-->x = [1, 1; 110, 30] \ [75; 4000] x = ! 21.875 ! ! 53.125 !
The acreage that results in the maximum profit is 21.875 for wheat and 53.125 for barley. In that case the profit is:
-->P = [143, 60] * x P = 6315.625
That is, $6315.625.
Note that these command are in script example3.sce
Now, lp_solve comes into the picture to solve this linear programming problem more generally. After that we will use it to solve two more complicated problems involving more variables and constraints.
For this example, we use the higher-level script lp_maker to build the model and then some lp_solve API calls to retrieve the solution. Here is again the usage of lp_maker:
LP_MAKER Makes mixed integer linear programming problems. SYNOPSIS: lp_handle = lp_maker(f,a,b,e,vlb,vub,xint,scalemode,setminim) make the MILP problem max v = f'*x a*x <> b x >= vlb >= 0 x <= vub x(int) are integer ARGUMENTS: The first four arguments are required: f: n vector of coefficients for a linear objective function. a: m by n matrix representing linear constraints. b: m vector of right sides for the inequality constraints. e: m vector that determines the sense of the inequalities: e(i) < 0 ==> Less Than e(i) = 0 ==> Equals e(i) > 0 ==> Greater Than vlb: n vector of non-negative lower bounds. If empty or omitted, then the lower bounds are set to zero. vub: n vector of upper bounds. May be omitted or empty. xint: vector of integer variables. May be omitted or empty. scalemode: scale flag. Off when 0 or omitted. setminim: Set maximum lp when this flag equals 0 or omitted. OUTPUT: lp_handle is an integer handle to the lp created.
Now let's formulate this model with lp_solve:
-->f = [143, 60]; -->A = [120, 210; 110, 30; 1, 1]; -->b = [15000, 4000, 75]; -->lp = lp_maker(f, A, b, [-1, -1, -1], [], [], [], 1, 0); -->solvestat = sclpsolve("solve", lp) solvestat = 0. -->sclpsolve("get_objective", lp) ans = 6315.625 -->sclpsolve("get_variables", lp) ans = ! 21.875 ! ! 53.125 ! -->sclpsolve("delete_lp", lp);
Note that these command are in script example4.oms
With the higher-level script lp_maker, we provide all data to lp_solve. lp_solve returns a handle (lp) to the created model. Then the API call 'solve' is used to calculate the optimal solution of the model. The value of the objective function is retrieved via the API call 'get_objective' and the values of the variables are retrieved via the API call 'get_variables'. At last, the model is removed from memory via a call to 'delete_lp'. Don't forget this to free all memory allocated by lp_solve.
The solution is the same answer we obtained before. Note that the non-negativity constraints are accounted implicitly because variables are by default non-negative in lp_solve.
Well, we could have done this problem by hand (as shown in the introduction) because it is very small and it
can be graphically presented.
Now suppose that the farmer is dealing with a third crop, say corn, and that the corresponding data is:
cost per acre $150.75 yield per acre 125 bushels profit per bushel $1.56
With three variables it is already a lot more difficult to show this model graphically. Adding more variables makes it even impossible because we can't imagine anymore how to represent this. We only have a practical understanding of 3 dimentions, but beyound that it is all very theorethical.
If we denote the number of acres allotted to corn by z, then the objective function becomes:
P = (110)(1.30)x + (30)(2.00)y + (125)(1.56) = 143x + 60y + 195z
And the constraint inequalities are:
120x + 210y + 150.75z <= 15000
110x + 30y + 125z <= 4000
x + y + z <= 75
x >= 0, y >= 0, z >= 0
The problem is solved with lp_solve as follows:
-->f = [143, 60, 195]; -->A = [120, 210, 150.75; 110, 30, 125; 1, 1, 1]; -->b = [15000, 4000, 75]; -->lp = lp_maker(f, A, b, [-1, -1, -1], [], [], [], 1, 0); -->solvestat = sclpsolve("solve", lp) solvestat = 0. -->sclpsolve("get_objective", lp) ans = 6986.8421 -->sclpsolve("get_variables", lp) ans = ! 0. ! ! 56.578947 ! ! 18.421053 ! -->sclpsolve("delete_lp", lp);
Note that these command are in script example5.oms
So the farmer should ditch the wheat and plant 56.5789 acres of barley and 18.4211 acres of corn.
There is no practical limit on the number of variables and constraints that Scilab can handle. Certainly none that the relatively unsophisticated user will encounter. Indeed, in many true applications of the technique of linear programming, one needs to deal with many variables and constraints. The solution of such a problem by hand is not feasible, and software like Scilab is crucial to success. For example, in the farming problem with which we have been working, one could have more crops than two or three. Think agribusiness instead of family farmer. And one could have constraints that arise from other things beside expenses, storage and acreage limitations. For example:
Below is a sequence of commands that solves exactly such a problem. You should be able to recognize the objective expression and the constraints from the data that is entered. But as an aid, you might answer the following questions:
-->f = [110*1.3, 30*2.0, 125*1.56, 75*1.8, 95*.95, 100*2.25, 50*1.35]; -->A = [120,210,150.75,115,186,140,85;110,30,125,75,95,100,50;1,1,1,1,1,1,1; 1,-1,0,0,0,0,0;0,0,1,0,-2,0,0;0,0,0,-1,0,-1,1]; -->b = [55000, 40000, 400, 0, 0, 0]; -->lp = lp_maker(f, A, b, [-1,-1,-1,-1,-1,-1],[10,10,10,10,20,20,20],[100,%inf,50,%inf,%inf,250,%inf],[],1,0); -->solvestat = sclpsolve("solve", lp) solvestat = 0. -->sclpsolve("get_objective", lp) ans = 75398.043 -->sclpsolve("get_variables", lp) ans = ! 10. ! ! 10. ! ! 40. ! ! 45.652174 ! ! 20. ! ! 250. ! ! 20. ! -->sclpsolve("delete_lp", lp);
Note that these command are in script example6.oms
Note that we have used in this formulation the vlb and vub arguments of lp_maker. This to set lower and upper bounds on variables. This could have been done via extra constraints, but it is more performant to set bounds on variables. Also note that %inf is used for variables that have no upper limit. This stands for Infinity.
Note that despite the complexity of the problem, lp_solve solves it almost instantaneously. It seems the farmer should bet the farm on crop number 6. We strongly suggest you alter the expense and/or the storage limit in the problem and see what effect that has on the answer.
Suppose we want to solve the following linear program using Scilab:
max 4x1 + 2x2 + x3
s. t. 2x1 + x2 <= 1
x1 + 2x3 <= 2
x1 + x2 + x3 = 1
x1 >= 0
x1 <= 1
x2 >= 0
x2 <= 1
x3 >= 0
x3 <= 2
Convert the LP into Scilab format we get:
f = [4, 2, 1]
A = [2, 1, 0; 1, 0, 2; 1, 1, 1]
b = [1, 2, 1]
Note that constraints on single variables are not put in the constraint matrix. lp_solve can set bounds on individual variables and this is more performant than creating additional constraints. These bounds are:
l = [ 0, 0, 0]
u = [ 1, 1, 2]
Now lets enter this in Scilab:
-->f = [4, 2, 1]; -->A = [2, 1, 0; 1, 0, 2; 1, 1, 1]; -->b = [1, 2, 1]; -->l = [ 0, 0, 0]; -->u = [ 1, 1, 2];
Now solve the linear program using Scilab: Type the commands
-->lp = lp_maker(f, A, b, [-1, -1, -1], l, u, [], 1, 0); -->solvestat = sclpsolve("solve", lp) solvestat = 0. -->sclpsolve("get_objective", lp) ans = 2.5 -->sclpsolve("get_variables", lp) ans = ! 0.5 ! ! 0. ! ! 0.5 ! -->sclpsolve("delete_lp", lp)
What to do when some of the variables are missing ?
For example, suppose there are no lower bounds on the variables. In this case define l to be the empty set using the Scilab command:
-->l = [];
This has the same effect as before, because lp_solve has as default lower bound for variables 0.
But what if you want that variables may also become negative?
Then you can use -%inf as lower bounds:
-->l = [-%inf, -%inf, -%inf];
Solve this and you get a different result:
-->lp = lp_maker(f, A, b, [-1, -1, -1], l, u, [], 1, 0); -->solvestat = sclpsolve("solve", lp) solvestat = 0. -->sclpsolve("get_objective", lp) ans = 2.6666667 -->sclpsolve("get_variables", lp) ans = ! 0.6666667 ! ! - 0.3333333 ! ! 0.6666667 ! -->sclpsolve("delete_lp", lp)
Note that everwhere where lp is used as argument that this can be a handle (lp_handle) or the models name.
These routines are not part of the lpsolve API, but are added for backwards compatibility. Most of them exist in the lpsolve API with another name.
Under Windows, the sclpsolve Scilab driver is a dll: sclpsolve.dll
Under Unix/Linux, the sclpsolve Scilab driver is a static library sclpsolve.a
The library is an interface to the lpsolve55 library that contains the implementation of lp_solve.
Under windows this is a dll lpsolve55.dll and under Unix/Linux it is a shared library liblpsolve55.so
They are distributed with the lp_solve package (archive lp_solve_5.5.0.13_dev.zip/lp_solve_5.5.0.13_dev.tar.gz). See at the beginning of this article where these files must be installed.
The sclpsolve Scilab driver is just
a wrapper between Scilab and lp_solve to translate the input/output to/from Scilab and the lp_solve library.
The sclpsolve Scilab driver is written in C. To compile this code, under Windows the Microsoft C compiler is needed and under
Unix the standard compiler is used.
This compiler must be called from Scilab. To make the compilation process easier, a script can be used:
builder.sce
Before the compilation is started, it may be necessary to edit the file Path.incl. In this file it is specified where scilab is installed
and were lp_solve is installed. Change the paths as needed.
To make everything, just enter exec builder.sce and everything is build.
This compiles the source files to the needed libraries, compiles the sci scripts and makes the manuals. It also
generates a new loader.sce file to load the driver into the Scilab workspace.
This build process is the same under Windows and Unix/Linux. Note that builder.sce generates Makefiles that are then used to build the code. Don't edit the Makefiles since your changes will be lost when build.sce is executed again.
See also Using lpsolve from MATLAB, Using lpsolve from O-Matrix, Using lpsolve from Octave, Using lpsolve from Python, Using lpsolve from R
docs/5.5/set_epsb.htm 0000644 0001750 0001750 00000007031 11306036626 013303 0 ustar rene rene
set_epsbSpecifies the value that is used as a tolerance for the Right Hand Side (RHS) to determine whether a value should be considered as 0. void set_epsb(lprec *lp, REAL epsb); Return Value set_epsb has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI epsb The value that is used as a tolerance for the Right Hand Side (RHS) to determine whether a value should be considered as 0. Remarks The set_epsb function specifies the value that is used as a tolerance for
the Right Hand Side (RHS) to determine whether a value should be considered as
0. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_epsb, set_infinite, get_infinite, is_infinite, set_epsint, get_epsint, set_epsd, get_epsd, set_epsel, get_epsel, get_epspivot, set_epspivot, set_epsperturb, get_epsperturb, set_mip_gap, get_mip_gap |
solvesolve the model. int solve(lprec *lp); Return Value
Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks
The solve function solves the model. solve can be called more
than once. Between calls, the model may be modified in every way. Restrictions
may be changed, matrix values may be changed and even rows and/or columns may
be added or deleted. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, lag_solve, statustext, is_feasible, get_objective, get_working_objective, get_variables, get_ptr_variables, get_constraints, get_ptr_constraints, get_constr_value, get_primal_solution, get_ptr_primal_solution, get_var_primalresult, get_sensitivity_rhs, get_ptr_sensitivity_rhs, get_dual_solution, get_ptr_dual_solution, get_var_dualresult, get_sensitivity_obj, get_ptr_sensitivity_obj, get_sensitivity_objex, get_ptr_sensitivity_objex |
has_BFPReturns if there is a basis factorization package (BFP) available. unsigned char has_BFP(lprec *lp); Return Value has_BFP returns TRUE if there is a BFP available, else FALSE. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks There should always be a BFP available, else lpsolve can not solve. Normally lpsolve is compiled with a default BFP. See Basis Factorization Packages for a complete description on BFPs. Example
See Also make_lp, copy_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, is_nativeBFP, set_BFP |
get_rh_rangeGets the range on a constraint. REAL get_rh_range(lprec *lp, int row); Return Value get_rh_range returns the range set on the constraint specified by row. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI row The row number of the constraint from which the range must be retrieved. It must be between 1 and the number of rows in the lp. Remarks The get_rh_range function gets the range on the constraint (row)
identified by row. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_rh_range |
set_debugSets a flag if all intermediate results and the branch-and-bound decisions must be printed while solving. void set_debug(lprec *lp, unsigned char debug); Return Value set_debug has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI debug TRUE or FALSE. Debug or do not debug. Remarks The set_debug function sets a flag if all intermediate results and the branch-and-bound decisions must be printed while solving. This function is mend for debugging purposes. The default is not to debug (FALSE). Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, is_debug |
set_unboundedSets if the variable is free. unsigned char set_unbounded(lprec *lp, int column); Return Value set_unbounded returns TRUE (1) if the variable could be set as free, FALSE (0)
otherwise. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI column The column number of the variable that must be set. It must be between 1 and the number of columns in the lp. Remarks The set_unbounded function sets if a variable is free or not. Free means a lower bound of -infinity and an upper bound of +infinity. Default a variable is not free because default it has a lower bound of 0 (and an upper bound of +infinity). See free variables for a description about free variables. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_upbo, set_upbo, set_lowbo, get_lowbo, set_bounds, is_unbounded, is_negative |
get_variables, get_ptr_variablesReturns the values of the variables. unsigned char get_variables(lprec *lp, REAL *var); unsigned char get_ptr_variables(lprec *lp, REAL **ptr_var); Return Value get_variables, get_ptr_variables returns TRUE (1) if the operation was
successful. A return value of FALSE (0) indicates an error. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI var An array that will contain the values of the variables. ptr_var The address of a pointer that will point to an array that will contain the values of the variables. Remarks The get_variables, get_ptr_variables functions retrieve the values
of the variables. Note that get_ptr_variables returns a pointer to memory allocated and maintained by lp_solve. Be careful what you do with it. Don't modify its contents or free the memory. Unexpected behaviour would occur. Also note that this memory pointer is only guaranteed to remain constant until a next lp_solve API call is done. You should call this function again to make sure you have again the correct pointer. Otherwise, this pointer could point to invalid memory. This should not be a problem since this call is very efficient. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, is_feasible, get_objective, get_working_objective, get_constraints, get_ptr_constraints, get_constr_value, get_primal_solution, get_ptr_primal_solution, get_var_primalresult, get_sensitivity_rhs, get_ptr_sensitivity_rhs, get_dual_solution, get_ptr_dual_solution, get_var_dualresult, get_sensitivity_obj, get_ptr_sensitivity_obj, get_sensitivity_objex, get_ptr_sensitivity_objex |
set_preferdualSets the desired combination of primal and dual simplex algorithms. void set_preferdual(lprec *lp, unsigned char dodual); Return Value set_preferdual has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI dodual
When TRUE, the simplex strategy is set to SIMPLEX_DUAL_DUAL. Remarks The set_preferdual function sets the desired combination of primal and dual simplex algorithms. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_simplextype |
The main things to know about fixed MPS format are that it is column oriented (as opposed to entering the model as equations), and everything (variables, rows, etc.) gets a name. MPS is an old format, so it is set up as though you were using punch cards, and is not free format. Fields start in column 2, 5, 15, 25, 40 and 50. Sections of an MPS file are marked by so-called header cards, which are distinguished by their starting in column 1. Although it is typical to use upper-case throughout the file (like I said, MPS has long historical roots), many MPS-readers will accept mixed-case for anything except the header cards, and some allow mixed-case anywhere. The names that you choose for the individual entities (constraints or variables) are not important to the solver; you should pick names that are meaningful to you, or will be easy for a post-processing code to read. Here is a little sample model written in MPS format (explained in more detail below): NAME TESTPROB ROWS N COST L LIM1 G LIM2 E MYEQN COLUMNS XONE COST 1 LIM1 1 XONE LIM2 1 YTWO COST 4 LIM1 1 YTWO MYEQN -1 ZTHREE COST 9 LIM2 1 ZTHREE MYEQN 1 RHS RHS1 LIM1 5 LIM2 10 RHS1 MYEQN 7 BOUNDS UP BND1 XONE 4 LO BND1 YTWO -1 UP BND1 YTWO 1 ENDATA For comparison, here is the same model written out in lp-format: min: +XONE +4 YTWO +9 ZTHREE; LIM1: +XONE +YTWO <= 5; LIM2: +XONE +ZTHREE >= 10; MYEQN: -YTWO +ZTHREE = 7; XONE <= 4; YTWO >= -1; YTWO <= 1; Strangely, there is nothing in MPS format that specifies the direction of optimisation. And there really is no standard "default" direction; some LP codes will maximize if you don't specify otherwise, others will minimize, and still others put safety first and have no default and require you to specify it somewhere in a control program or by a calling parameter. If you have a model formulated for minimization and the code you are using insists on maximization (or vice versa), it may be easy to convert: just multiply all the coefficients in your objective function by (-1). The optimal value of the objective function will then be the negative of the true value, but the values of the variables themselves will be correct. Any line with an asterisk (*) in Column 1 is treated as a comment. The eight character names used to specify variables, constraints and other entities are fixed format. Names are not automatically justified, so blanks are treated just like other characters. For example "ROW1 " is not the same as " ROW1 ". (Note that some optimisers do not permit blanks in names.) No case conversion is performed, so "row1 " is different from "ROW1 ". Floating point numbers may be specified in free format within the 12 character field (including embedded blanks). The following list describes the possible ways of writing a number. Mantissa: + or - optional sign character (no sign indicates a positive number) digits optional integer part of the mantissa . optional decimal point (if not present, a decimal point will be assumed after the mantissa digit) digits optional fraction part of the mantissa -the mantissa must contain at least one digit Exponent (optional): D or E exponent leader + or - optional exponent sign digits exponent digits Numbers with an absolute value greater than 1010 or less than 10-10 are rejected. The NAME card can have anything you want, starting in column 15. The ROWS section defines the names of all the constraints; entries in column 2 or 3 are E for equality rows, L for less-than ( <= ) rows, G for greater-than ( >= ) rows, and N for non-constraining rows (the first of which would be interpreted as the objective function). The order of the rows named in this section is unimportant. The largest part of the file is in the COLUMNS section, which is the place where the entries of the A-matrix are put. All entries for a given column must be placed consecutively, although within a column the order of the entries (rows) is irrelevant. Rows not mentioned for a column are implied to have a coefficient of zero. The RHS section allows one or more right-hand-side vectors to be defined; most people don't bother having more than one. In the above example, the name of the RHS vector is RHS1, and has non-zero values in all 3 of the constraint rows of the problem. Rows not mentioned in an RHS vector would be assumed to have a right-hand-side of zero. The optional BOUNDS section lets you put lower and upper bounds on individual variables (no * wild cards, unfortunately), instead of having to define extra rows in the matrix. All the bounds that have a given name in column 5 are taken together as a set. Variables not mentioned in a given BOUNDS set are taken to be non-negative (lower bound zero, no upper bound). A bound of type UP means an upper bound is applied to the variable. A bound of type LO means a lower bound is applied. A bound type of FX ("fixed") means that the variable has upper and lower bounds equal to a single value. A bound type of FR ("free") means the variable has neither lower nor upper bounds. There is another optional section called RANGES that I won't go into here. The final card must be ENDATA, and yes, it is spelled funny. ========================================================================== MPS input format was originally introduced by IBM to express linear and integer programs in a standard way. The format is a fixed column format, so care must be taken that all information is placed in the correct columns as described below. The following is not intended as a complete description of MPS format, but only as a brief introduction. For more information, the reader is directed to: "Advanced Linear Programming," by Bruce A. Murtagh "Computer Solutions of Linear Programs," by J.L. Nazareth It may be useful to look at an example MPS file while reading this MPS information. The following template is a guide for the use of MPS format: --------------------------------------------------------------------- Field: 1 2 3 4 5 6 Columns: 2-3 5-12 15-22 25-36 40-47 50-61 NAME problem name ROWS type name COLUMNS column row value row value name name name RHS rhs row value row value name name name RANGES range row value row value name name name BOUNDS type bound column value name name SOS type CaseName SOSName SOSpriority CaseName VarName1 VarWeight1 CaseName VarName2 VarWeight2 CaseName VarNameN VarWeightN ENDATA --------------------------------------------------------------------- NOTES: A. In the ROWS section, each row of the constraint matrix must have a row type and a row name specified. The code for indicating row type is as follows: type meaning --------------------------- E equality L less than or equal G greater than or equal N objective N no restriction B. In the COLUMNS section, the names of the variables are defined along with the coefficients of the objective and all the nonzero constraint matrix elements. It is not necessary to specify columns for slack or surplus variables as this is taken care of automatically. C. The RHS section contains information for the right-hand side of the problem. D. The RANGES section is for constraints of the form: h <= constraint <= u . The range of the constraint is r = u - h . The value of r is specified in the RANGES section, and the value of u or h is specified in the RHS section. If b is the value entered in the RHS section, and r is the value entered in the RANGES section, then u and h are thus defined: row type sign of r h u ---------------------------------------------- G + or - b b + |r| L + or - b - |r| b E + b b + |r| E - b - |r| b E. In the BOUNDS section, bounds on the variables are specified. When bounds are not indicated, the default bounds ( 0 <= x < infinity ) are assumed. The code for indicating bound type is as follows: type meaning --------------------------------------------------- LO lower bound b <= x (< +inf) UP upper bound (0 <=) x <= b FX fixed variable x = b FR free variable -inf < x < +inf MI lower bound -inf -inf < x (<= 0) PL upper bound +inf (0 <=) x < +inf BV binary variable x = 0 or 1 LI integer variable b <= x (< +inf) UI integer variable (0 <=) x <= b SC semi-cont variable x = 0 or l <= x <= b l is the lower bound on the variable If none set then defaults to 1 F. Sections RANGES and BOUNDS are optional as are the fields 5 and 6. Everything else is required. In regards to fields 5 and 6, consider the following 2 constraints: const1: 2x + 3y <= 6 const2: 5x + 8y <= 20 Two ways to enter the variable x in the COLUMNS section are: (Field: 2 3 4 5 6 ) 1. x const1 2.0 const2 5.0 2. x const1 2.0 x const2 5.0 G. A mixed integer program requires the specification of which variables are required to be integer. Markers are used to indicate the start and end of a group of integer variables. The start marker has its name in field 2, 'MARKER' in field 3, and 'INTORG' in field 5. The end marker has its name in field 2, 'MARKER' in field 3, and 'INTEND' in field 5. These markers are placed in the COLUMNS section. H. A specially ordered set of degree N is a collection of variables where at most N variables may be non-zero. The non-zero variables must be contiguous (neighbours) sorted by the ascending value of their respective unique weights. In lp_solve, specially ordered sets may be of any cardinal type 1, 2, and higher, and may be overlapping. The number of variables in the set must be equal to, or exceed the cardinal SOS order. Below is a representation of a SOS in an MPS file, where each SOS is defined in its own SOS section, which should follow the BOUNDS section. 0 1 2 3 4 1234567890123456789012345678901234567890 SOS Sx CaseName SOSName. SOSpriority. CaseName VarName1 VarWeight1.. CaseName VarName2 VarWeight2.. CaseName VarNameN VarWeightN.. x at the second line, position 3, defines is the order of the SOS. Due to limitations in the MPS format, N is restricted to the 1..9 range. Each SOS should be given a unique name, SOSName. lp_solve does not currently use case names for SOS'es and the CaseName could be any non-empty value. The SOSpriority value determines the order in which multiple SOS'es are analysed in lp_solve. See also Interpolation with GAMS.
Example:
NAME SOS2test ROWS N obj L c1 L c2 E c3 COLUMNS x1 obj -1 c1 -1 x1 c2 1 x2 obj -2 c1 1 x2 c2 -3 c3 1 x3 obj -3 c1 1 x3 c2 1 x4 obj -1 c1 10 x4 c3 -3.5 x5 obj 0 RHS rhs c1 30 c2 30 BOUNDS UP BOUND x1 40 LI BOUND x4 2 UI BOUND x4 3 SOS S2 SET SOS2 10 SET x1 10000 SET x2 20000 SET x4 40000 SET x5 50000 ENDATA
The free format is very similar to the fixed MPS format, but it is less restrictive e.g. it allows longer names. Also some implementations allow more than 12 positions to specify the values. The fields do not have fixed column positions as in the fixed MPS format. They may be written anywhere except column 1, with each field separated from the next by one or more blanks. However, they must appear in the same sequence as in fixed format. In the rows and bounds sections, the codes can be lower and upper case and at any starting position. Repeated column names are sometimes skipped and spaces are put there instead. The Fortran D exponent is allowed in the values.
There is one important limitation compared to the fixed MPS format: names may not contain blanks.
Note that the free MPS parser cannot read all fixed MPS formats correctly. Spaces in the names or names starting with spaces will give problems. It is not sure that an error will be given in that case. If the format complies to the free MPS format then it won't... So if you know that a model is in fixed MPS format, use it and not the free format. It is advised to first try the fixed format and only if it doesn't work, use the free format.
Also note that there is no real standard for the free format. Each implementer has its own implementation and interpretation of the free format ... Some allow one space in the name, some require that names must take at least 8 positions (and thus extended with spaces). Some allow to have more than 6 fields on a line. lp_solve only reads the first 6 fields and ignores the rest.
lp_solve tries to handle all possible free formats. The only real limitation is that there may be no blanks in names (also no leading blanks) and only 6 fields per line may be used. When lp_solve writes an mps file in free format, it will be the same as for fixed format, except if names are longer than 8 characters. In that case all data is shifted to the right.
Several solvers have added a 'standard' to the free MPS format to allow to specify the objective direction.
This via the new optional section OBJSENSE. Below this section, there may be one line that specifies the objective direction.
This in field 1 of this line via the following possible keywords: MAXIMIZE, MAX, MINIMIZE, MIN. If the section
is not specified, then lp_solve assumes minimization, just like the fixed MPS format.
For example:
OBJSENSE MAX
This section should be before the ROWS section.
For example:
NAME TESTPROB OBJSENSE MAX ROWS N COST L LIM1 G LIM2 E MYEQN COLUMNS XONE COST 1 LIM1 1 XONE LIM2 1 YTWO COST 4 LIM1 1 YTWO MYEQN -1 ZTHREE COST 9 LIM2 1 ZTHREE MYEQN 1 RHS RHS1 LIM1 5 LIM2 10 RHS1 MYEQN 7 BOUNDS UP BND1 XONE 4 LO BND1 YTWO -1 UP BND1 YTWO 1 ENDATA
The lp_solve free MPS reader recognises and interprets all possible OBJSENSE direction values. When a free MPS file is created, the OBJSENSE section will only be written when the direction is maximization. This because minimization is by default assumed and to stay as compatible as possible with other solvers.
Several solvers have added a 'standard' to the free MPS format to allow to specify the objective row.
By default the first "N" row defined in the ROWS section becomes a problem's objective; a different objective may be
specified in the optional OBJNAME section, which contains exactly one data line that names the objective in field 1.
For example:
OBJNAME obj2
This section should be before the ROWS section.
For example:
NAME TESTPROB OBJNAME PROFIT ROWS N COST N PROFIT L LIM1 G LIM2 E MYEQN COLUMNS XONE COST -1 PROFIT 1 XONE LIM1 1 LIM2 1 YTWO COST -4 PROFIT 4 YTWO LIM1 1 MYEQN -1 ZTHREE COST -9 PROFIT 9 ZTHREE LIM2 1 MYEQN 1 RHS RHS1 LIM1 5 LIM2 10 RHS1 MYEQN 7 BOUNDS UP BND1 XONE 4 LO BND1 YTWO -1 UP BND1 YTWO 1 ENDATA
The lp_solve free MPS reader recognises and interprets this OBJNAME section and uses the objective name specified here. Other "N" cards in the ROWS section are then ignored. Note that if there is no OBJNAME section that, just like in the fixed MPS format, the first "N" card from the rows section is then taken and all other "N" cards are ignored. When a free MPS file is created, the OBJNAME section will never be created since lp_solve always only has one objective function in memory.
docs/5.5/read_XLI.htm 0000644 0001750 0001750 00000006271 11306036626 013133 0 ustar rene rene
read_XLICreate an lprec structure and read a model via the External Language Interface. lprec *read_XLI(char *xliname, char *modelname, char *dataname, char *options, int verbose); Return Value
Returns a pointer to a new lprec structure. This must be provided to almost all
lp_solve functions. Parameters xliname Filename of the XLI package. modelname Filename to read the model from. dataname Filename to read the data from. This may be optional. In that case, set the parameter to NULL. options Extra options that can be used by the reader. verbose The verbose level. Can be one of the following values: See also set_verbose and get_verbose. Remarks The read_XLI function constructs a new lprec structure and reads the model from filename via the specified XLI. See External Language Interfaces for a complete description on XLIs. Example
See Also delete_lp, free_lp, make_lp, copy_lp, write_lp, write_LP, write_lpex, read_mps, read_freemps, read_MPS, read_freeMPS, write_mps, write_freemps, write_MPS, write_freeMPS, MPS_writefileex, write_XLI, has_XLI, is_nativeXLI, set_XLI |
set_boundsSet the upper and lower bound of a variable. unsigned char set_bounds(lprec *lp, int column, REAL lower, REAL upper); Return Value set_bounds returns TRUE (1) if the operation was successful. A return
value of FALSE (0) indicates an error. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI column The column number of the variable on which the bounds must be set. It must be between 1 and the number of columns in the lp. Remarks The set_bounds function sets a lower and upper bound on the variable
identified by column. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_lowbo, get_lowbo, set_upbo, get_upbo, set_unbounded, is_unbounded, is_negative |
get_statusReturns an extra status after a call to a function. int get_status(lprec *lp); Return Value Extra status which indicates type of problem after call to function. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The get_status function returns an extra status after a call to a function. Some functions return FALSE when they have failed. To have more information on the reason of the failure, this routine can be used to get an extended error code. Example
See Also free_lp, make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI |
lpsolve distributed fileslpsolve is distributed as several separate archive files. It is most unlikely that you need them all for your purpose. This text describes each archive's contents. There are two kind of archive files:
Ziped files are basically binaries (executables/libraries) for the Windows platform. gziped tar files can be divided into two categories:
List of archives
|
has_XLIReturns if there is an external language interface (XLI) set. unsigned char has_XLI(lprec *lp); Return Value has_XLI returns TRUE if there is an XLI set, else FALSE. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks See External Language Interfaces for a complete description on XLIs. Example
See Also make_lp, copy_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, write_XLI, is_nativeXLI, set_XLI |
set_pivotingSets the pivot rule and mode. void set_pivoting(lprec *lp, int pivoting); Return Value set_pivoting has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI pivoting The pivot rule and mode. Can be one of the following rules:
Some of these values can be combined with any (ORed) of the following modes:
Remarks The set_pivoting function specifies the pivot rule (rule for selecting row
and column entering/leaving) and mode. The rule is an exclusive option and the mode
is a modifier to the rule. This rule/mode can influence solving times
considerably. Depending on the model one rule/mode can be best and for another model
another rule/mode. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_pivoting, is_piv_rule, is_piv_mode |
PresolvePresolve 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.
Presolve is not active by default. It must specifically being enabled via the API call set_presolve. A simple example: max: x1 + x2 + x3; r1: x2 = 2; r2: x1 + x2 <= 6; r3: x1 - 2 x3 >= 2; r4: x2 + 3 x3 <= 5; 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: lp_solve model.lp -wlp con -S1 -wafter -presolverow /* Objective function */ max: +x1 +x2 +x3; /* Constraints */ r2: +x1 +x2 <= 6; r3: +x1 -2 x3 >= 2; r4: +x2 +3 x3 <= 5; /* Variable bounds */ x2 = 2;
And even this model can be presolved further. lp_solve model.lp -wlp con -S1 -wafter -presolverow -presolvecol /* Objective function */ max: +x1 +x3 +2; /* Constraints */ r3: +x1 -2 x3 >= 2; /* Variable bounds */ x1 <= 4; x3 <= 1; 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.
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. Example in C: #include <stdio.h> #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); } This gives: /* Objective function */ max: +x1 +x2 +x3; /* Constraints */ R1: +x2 = 2; R2: +x1 +x2 <= 6; R3: +x1 -2 x3 >= 2; R4: +x2 +3 x3 <= 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 -> 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 < Z < +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 >= 2; /* Variable bounds */ x1 <= 4; x3 <= 1;
The result only shows values of contraint R3, the one that is kept.
The information of the removed constraints is no longer there. Almost all API calls return information of the presolved model. get_Nrows and get_Ncolumns return the number of rows and columns of the presolved model. To know the original values, get_Norig_rows and get_Norig_columns must be used: 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
To retrieve the variable data of all variables, including the presolved variables, API call
get_var_primalresult must be used.
This is the only call available to get all information. int column, Nrows, Ncolumns; Ncolumns = get_Norig_columns(lp); Nrows = get_Norig_rows(lp); for (column = 1; column <= Ncolumns; column++) { printf("x%d: %f\n", column, get_var_primalresult(lp, Nrows + column)); } With result: x1: 4.000000 x2: 2.000000 x3: 1.000000
get_var_primalresult also returns information about rows. int row, Nrows; Nrows = get_Norig_rows(lp); for (row = 1; row <= Nrows; row++) { printf("R%d: %f\n", row, get_var_primalresult(lp, row)); } With result: R1: 0.000000 R2: 0.000000 R3: 2.000000 R4: 0.000000 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!
There is also a possibility to know which rows and columns are removed from the model.
get_orig_index can be used for that. int row, Nrows; int column, Ncolumns; Ncolumns = get_Ncolumns(lp); Nrows = get_Nrows(lp); for (row = 1; row <= Nrows; row++) printf("row %d was row R%d\n", row, get_orig_index(lp, row)); for (column = 1; column <= Ncolumns; column++) printf("column %d was column x%d\n", column, get_orig_index(lp, Nrows + column)); With result: row 1 was row R3 column 1 was column x1 column 2 was column x3 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. Again note that all other API calls return information about the presolved model. So for example get_ptr_primal_solution must be used like this: int row, Nrows; int column, Ncolumns; double *pv; get_ptr_primal_solution(lp, &pv); Ncolumns = get_Ncolumns(lp); Nrows = get_Nrows(lp); for (row = 1; row <= Nrows; row++) printf("row %d: %f\n", row, pv[row]); for (column = 1; column <= Ncolumns; column++) printf("column %d: %f\n", column, pv[Nrows + column]); With result: row 1: 2.000000 column 1: 4.000000 column 2: 1.000000 Row and column names of the original model can be obtained via get_origrow_name and get_origcol_name: int row, Nrows; int column, Ncolumns; Ncolumns = get_Norig_columns(lp); Nrows = get_Norig_rows(lp); for (row = 1; row <= Nrows; row++) printf("row %d: %s\n", row, get_origrow_name(lp, row)); for (column = 1; column <= Ncolumns; column++) printf("column %d: %s\n", column, get_origcol_name(lp, column)); With result: row 1: R1 row 2: R2 row 3: R3 row 4: R4 column 1: x1 column 2: x2 column 3: x3 Row and column names of the presolved model can be obtained via get_row_name and get_col_name: int row, Nrows; int column, Ncolumns; Ncolumns = get_Ncolumns(lp); Nrows = get_Nrows(lp); for (row = 1; row <= Nrows; row++) printf("row %d: %s\n", row, get_row_name(lp, row)); for (column = 1; column <= Ncolumns; column++) printf("column %d: %s\n", column, get_col_name(lp, column)); With result: row 1: R3 column 1: x1 column 2: x3 |
get_orig_indexReturns the original row/column where a constraint/variable was before presolve. int get_orig_index(lprec *lp, int lp_index); Return Value get_orig_index returns the original row/column where a constraint/variable was before presolve. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI lp_index constraint or column number. If lp_index is between 1 and get_Nrows then the index is a constraint (row) number. If lp_index is between 1+get_Nrows and get_Nrows + get_Ncolumns then the index is a column number. Remarks The get_orig_index function returns the original row/column where a constraint/variable was before presolve. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_lp_index, get_Ncolumns, get_Norig_columns, get_Nrows, get_Norig_rows, get_Lrows, get_lp_index |
get_print_solReturns a flag if all intermediate valid solutions must be printed while solving. int get_print_sol(lprec *lp); Return Value get_print_sol returns the debug print status. Can by any of following values: Can be any of the following values:
Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The get_print_sol function returns a flag if all intermediate valid solutions must be printed while solving. Can give you useful solutions even if the total run time is too long. This function is mend for debugging purposes. The default is not to print (FALSE). Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_print_sol |
set_constr_typeSet the type of a constraint. unsigned char set_constr_type(lprec *lp, int row, int con_type); Return Value set_constr_type returns TRUE (1) if the operation was successful. A
return value of FALSE (0) indicates an error. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI row The row for which the constraint type must be set. Must be between 1 and number of rows in the lp. con_type The type of the constraint. Can by any of the following values:
Remarks The set_constr_type function sets the constraint type for the specified
row. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_constr_type, is_constr_type, add_constraint, add_constraintex, str_add_constraint, del_constraint |
get_basiscrashDetermines a starting base. int get_basiscrash(lprec *lp); Return Value Specifies which basis crash mode is used. Can by any of the following values:
Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The get_basiscrash function returns which basis crash mode must be used. Default is CRASH_NONE. When no base crash is done (the default), the initial basis from which lp_solve starts to solve the model is the basis containing all slack or artificial variables that is automatically associates with each constraint. When base crash is enabled, a heuristic ``crash procedure'' is executed before the first simplex iteration to quickly choose a basis matrix that has fewer artificial variables. This procedure tends to reduce the number of iterations to optimality since a number of iterations are skipped. lp_solve starts iterating from this basis until optimality. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_basiscrash, default_basis, get_basis, set_basis, read_basis, write_basis, guess_basis |
delete_lpDeletes an lprec structure. void delete_lp(lprec *lp); Return Value None Parameters lp lprec structure to delete. Remarks The delete_lp function frees all memory allocated to the lp structure. Example
See Also free_lp, make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI |
set_BFPSet basis factorization package. unsigned char set_BFP(lprec *lp, char *filename); Return Value set_BFP returns TRUE if the call has succeeded, else FALSE. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI filename The name of the BFP package. Currently following BFPs are implemented:
Remarks The set_BFP function sets the basis factorization package (BFP). See Basis Factorization Packages for a complete description on BFPs. Example
See Also make_lp, copy_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, has_BFP, is_nativeBFP |
get_Norig_columnsReturns the number of original columns (variables) in the lp. int get_Norig_columns(lprec *lp); Return Value get_Norig_columns returns the number of original columns (variables) in
the lp. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The get_Norig_columns function returns the number of original columns
(variables) in the lp. Example
See Also make_lp, copy_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_Ncolumns, get_Nrows, get_Norig_rows, get_orig_index, get_lp_index, get_Lrows |
is_integerscalingReturns if integer scaling is active. unsigned char is_integerscaling(lprec *lp); Return Value is_integerscaling returns if integer scaling is active (SCALE_INTEGERS set in get_scalelimit) Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The is_integerscaling function returns if integer scaling is active (SCALE_INTEGERS set in get_scalelimit). By default integers are not scaled. set_scaling must be called to active this feature. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_scaling, set_scaling, set_scalelimit, get_scalelimit |
set_binarySet the type of the variable. Binary or floating point. unsigned char set_binary(lprec *lp, int column, unsigned char must_be_bin); Return Value set_binary returns TRUE (1) if the operation was successful. A return
value of FALSE (0) indicates an error. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI column The column number of the variable that must be set. It must be between 1 and the number of columns in the lp. must_be_bin TRUE (1) if the variable must be binary, FALSE (0) if not. Remarks The set_binary function defines if a variable must be binary or not. Default a variable is not binary. A binary variable is an integer variable with a lower bound of 0 and an upper bound of 1. This function also sets these bounds. The argument must_be_bin defines what the status of the variable becomes. From the moment there is at least one integer variable in the model, the Branch and Bound algorithm is used to make these variables integer. Note that solving times can be considerably larger when there are integer variables. See integer variables for a description about integer variables. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, is_binary, is_int, set_int |
is_break_at_firstReturns if the branch-and-bound algorithm stops at first found solution. unsigned char is_break_at_first(lprec *lp); Return Value is_break_at_first returns if the branch-and-bound algorithm stops at
first found solution. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The is_break_at_first function returns if the branch-and-bound algorithm
stops at the first found solution or not. Stopping at the first found solution
can be useful if you are only interested for a solution, but not necessarily
(and most probably) the most optimal solution. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_break_at_first, set_break_at_value, get_break_at_value, set_obj_bound, get_obj_bound, set_mip_gap, get_mip_gap |
free_lpDeletes an lprec structure and initialise the plp variable. void free_lp(lprec **plp); Return Value None Parameters plp lprec structure to delete. After the call, *plp will be set to NULL. Remarks The free_lp function frees all memory allocated to the lp structure and initialises the *plp variable. Example
See Also delete_lp, make_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI |
get_col_name, get_origcol_nameGets the name of a column in the lp. char *get_col_name(lprec *lp, int column); char *get_origcol_name(lprec *lp, int column); Return Value get_col_name and get_origcol_name return the name of the specified column. A return value of NULL indicates an error. The difference between get_col_name and get_origcol_name is only visible when a presolve (set_presolve) was done. Presolve can result in deletion of columns in the model. In get_col_name, column specifies the column number after presolve was done. In get_origcol_name, column specifies the column number before presolve was done, ie the original column number. If presolve is not active then both functions are equal. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI column The column for which the name must be retrieved. Must be between 1 and the number of columns in the lp. In get_col_name, column specifies the column number after presolve was done. In get_origcol_name, column specifies the column number before presolve was done, ie the original column number. Remarks The get_col_name and get_origcol_name functions return the name of
the column. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_col_name, set_row_name, get_row_name, get_origrow_name, get_nameindex |
set_maxpivotSets the maximum number of pivots between a re-inversion of the matrix. void set_maxpivot(lprec *lp, int max_num_inv); Return Value set_maxpivot has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI max_num_inv The maximum number of pivots between a re-inversion of the matrix. Remarks The set_maxpivot function sets the maximum number of pivots between a
re-inversion of the matrix. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_maxpivot |
get_infiniteReturns the value of "infinite". REAL get_infinite(lprec *lp); Return Value get_infinite returns the value of "infinite". Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The get_infinite function returns the practical value for "infinite".
This value is used for very big numbers. For example the upper bound of a
variable without an upper bound. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_infinite, is_infinite, set_epsint, get_epsint, set_epsb, get_epsb, set_epsd, get_epsd, set_epsel, get_epsel, get_epspivot, set_epspivot, set_epsperturb, get_epsperturb |
get_epspivotReturns epspivot. REAL get_epspivot(lprec *lp); Return Value get_epspivot returns the value of epspivot. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The get_epspivot function returns the value that is used as a tolerance
for the pivot element to determine whether a value should be considered as 0. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_epspivot, set_infinite, get_infinite, set_epsint, get_epsint, set_epsd, get_epsd, set_epsel, get_epsel, get_epsperturb, set_epsperturb, set_mip_gap, get_mip_gap |
is_piv_ruleChecks if the specified pivot rule is active. unsigned char is_piv_rule(lprec *lp, int rule); Return Value is_piv_rule returns TRUE if the specified pivot rule is active, else FALSE Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI rule Can be one of the following values:
Remarks This rule can influence solving times
considerably. Depending on the model one rule can be best and for another model
another rule. Example
See Also make_lp, copy_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_pivoting, set_pivoting, is_piv_mode |
reset_basisCauses reinversion at next opportunity void reset_basis(lprec *lp); Return Value reset_basis has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks
This routine is ment for internal use and development.
It causes a reinversion of the matrix at a next opportunity.
The routine should only be used by people deeply understanding the code. See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_basis, set_basis, default_basis, get_basiscrash set_basiscrash |
set_minimSet objective function to minimize. void set_minim(lprec *lp); Return Value set_minim has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The set_minim function sets the objective direction to minimize. The default of lp_solve is to minimize, except for read_lp, read_LP where the default is to maximize. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_maxim, is_maxim, set_sense |
The MPS format can also be used to specify some predefined basis for an LP problem, i.e. to specify which rows and columns are basic and which are non-basic.
As in the MPS format, a number of fields are defined on fixed column positions:
Field: 1 2 3 4 5 6 Columns: 2-3 5-12 15-22 25-36 40-47 50-61
The order of a basis file in the MPS format is:
Any line with an asterisk (*) in Column 1 is treated as a comment.
The NAME card can have anything you want, starting in column 15.
lp_solve sets the number of iterations, the number of rows and number of columns of the model to the NAME
record.
The eight character names used to specify variables and constraints entities are fixed format. Names are not automatically justified, so blanks are treated just like other characters. For example "ROW1 " is not the same as " ROW1 ". (Note that some optimisers do not permit blanks in names.) No case conversion is performed, so "row1 " is different from "ROW1 ".
Each data card specifies either a pair "basic column--non-basic row" or a non-basic column. All the data cards have the following format.
'XL
' in the field 1 means that a column, whose name is given in
the field 2, is basic, and a row, whose name is given in the field 3,
is non-basic and placed on its lower bound.
'XU
' in the field 1 means that a column, whose name is given in
the field 2, is basic, and a row, whose name is given in the field 3,
is non-basic and placed on its upper bound.
'LL
' in the field 1 means that a column, whose name is given in
the field 3, is non-basic and placed on its lower bound.
'UL
' in the field 1 means that a column, whose name is given in
the field 3, is non-basic and placed on its upper bound.
The field 2 contains a column name.
If the indicator given in the field 1 is 'XL
' or 'XU
',
the field 3 contains a row name. Otherwise, if the indicator is
'LL
' or 'UL
', the field 3 is not used and should be empty.
The field 4, 5, and 6 are not used and should be empty.
Value | Status |
---|---|
XU | Variable 1 is basic; variable 2 is nonbasic at its upper bound |
XL | Variable 1 is basic; variable 2 is nonbasic at its lower bound |
UL | Variable 1 is nonbasic and is at its upper bound |
LL | Variable 1 is nonbasic and is at its lower bound |
Field 1: Indicator specifying status of the named variables in Fields 2 and 3.
Field 2: Variable 1 identifier
Field 3: Variable 2 identifier (ignored if Field 1 is UL
or LL
)
Variable 1 specifies a structural variable identifier which has entered the basis. By convention, this structural variable must displace one of the row variables. Variable 2 is a row variable that has left the basis. No relationship between structural variables entering the basis and row variables leaving the basis is implied within the BAS file.
A basis file in the MPS format acts like a patch: it doesn't specify a basis completely, instead that it is just shows in what a given basis differs from the "standard" basis, where all rows (auxiliary variables) are assumed to be basic and all columns (structural variables) are assumed to be non-basic.
A basis defines a list of basic structural variables and row variables. A structural variable is one of the variables (columns) defined in the MPS problem file. A row variable is actually the slack, surplus, or artificial variable associated with a row. The total number of basic variables-both structural and row-is equal to the number of rows in the constraint matrix. Additionally, the number of basic structural variables is equal to the number of nonbasic row variables. By convention, an MPS basis file is built on the assumption that all row variables are basic and that all structural variables are nonbasic with values at their lower bound. The data records in a BAS file list structural and row variables that violate this assumption. This convention minimizes the size of the BAS file.
Example:
*000000001111111111222222222233333333334444444444555555555566 *234567890123456789012345678901234567890123456789012345678901 NAME TESTPROB Iterations 0 Rows 3 Cols 3 XL ZTHREE LIM2 UL XONE ENDATAdocs/5.5/Java/ 0000755 0001750 0001750 00000000000 11306036627 011646 5 ustar rene rene docs/5.5/Java/docs/ 0000755 0001750 0001750 00000000000 11306036627 012576 5 ustar rene rene docs/5.5/Java/docs/api/ 0000755 0001750 0001750 00000000000 11306036627 013347 5 ustar rene rene docs/5.5/Java/docs/api/lpsolve/ 0000755 0001750 0001750 00000000000 11306036627 015033 5 ustar rene rene docs/5.5/Java/docs/api/lpsolve/package-summary.html 0000644 0001750 0001750 00000017371 11306036626 021017 0 ustar rene rene
|
|||||||||
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |
See:
Description
Interface Summary | |
AbortListener | Classes that implement this interface may be passed
to the putAbortfunc method of the LpSolve class. |
BbListener | Classes that implement this interface may be passed
to the putbbBranchfunc and putbbNodefunc method
of the LpSolve class. |
LogListener | Classes that implement this interface may be passed
to the putLogfunc method of the LpSolve class. |
MsgListener | Classes that implement this interface may be passed
to the putMsgfunc method of the LpSolve class. |
Class Summary | |
LpSolve | Object wrapper for a problem structure of the lp_solve library. |
VersionInfo | Contains the full version info for a lp_solve library instance. |
Exception Summary | |
LpSolveException | Exception thrown by the native methods in the C stub DLL. |
This package contains the files for the Java wrapper for the lp_solve optimization library. See the file README.html in the root direcory of the distribution archive for details.
|
|||||||||
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |
AbortListener
BbListener LogListener LpSolve LpSolveException MsgListener VersionInfo |
This file contains a reference for all methods in the lp_solve library and the Java wrapper. The first column of the following table contains the C functions of the lp_solve library, the second column the corresponding methods of the Java wrapper.
C function | Java wrapper method (LpSolve class) |
---|---|
unsigned char add_column (lprec* lp, REAL* column) | void addColumn(double[] column) throws LpSolveException |
unsigned char add_columnex (lprec* lp, int count, REAL* column, int* rowno) | void addColumnex(int count, double[] column, int[] rowno) throws LpSolveException |
unsigned char add_constraint (lprec* lp, REAL *row, int constr_type, REAL rh) | void addConstraint(double[] row, int constrType, double rh) throws LpSolveException |
unsigned char add_constraintex (lprec *lp, int count, REAL *row, int *colno, int constr_type, REAL rh) | void addConstraintex(int count, double[] row, int[] colno, int constrType, double rh) throws LpSolveException |
unsigned char add_lag_con (lprec* lp, REAL *row, int con_type, REAL rhs) | void addLagCon(double[] row, int constrType, double rh) throws LpSolveException |
int add_SOS (lprec* lp, char *name, int sostype, int priority, int count, int *sosvars, REAL *weights) | void addSOS(String name, int sostype, int priority, int count, int[] sosvars, double[] weights) throws LpSolveException |
int column_in_lp (lprec* lp, REAL *column) | int columnInLp(double[] column) |
void default_basis (lprec* lp) | void defaultBasis() |
unsigned char del_column(lprec *lp, int column) | void delColumn(int columnnr) throws LpSolveException |
unsigned char del_constraint(lprec *lp, int del_row) | void delConstraint(int rownr) throws LpSolveException |
void delete_lp(lprec *lp) | void deleteLp() |
void free_lp(lprec **plp) | <Not implemented, use deleteLp() instead> |
int get_anti_degen(lprec *lp) | int getAntiDegen() |
void get_basis(lprec *lp, int *bascolumn, unsigned char nonbasic) | void getBasis(int[] bascolumn, boolean nonbasic) |
int get_basiscrash(lprec *lp) | int getBasiscrash() |
int get_bb_depthlimit(lprec *lp) | int getBbDepthlimit() |
int get_bb_floorfirst(lprec *lp) | int getBbFloorfirst() |
int get_bb_rule(lprec *lp) | int getBbRule() |
unsigned char get_bounds_tighter(lprec *lp) | boolean getBoundsTighter() |
REAL get_break_at_value(lprec *lp) | double getBreakAtValue() |
char *get_col_name(lprec *lp, int column) | String getColName(int colnr) throws LpSolveException |
unsigned char get_column(lprec *lp, int col_nr, REAL *column) | void getColumn(int columnrnr, double[] column) throws LpSolveException |
<Not implemented> | double[] getPtrColumn(int columnrnr) throws LpSolveException |
int get_constr_type(lprec *lp, int row) | short getConstrType(int rownr) throws LpSolveException |
unsigned char get_constraints(lprec *lp, REAL *constr) | void getConstraints(double[] var) throws LpSolveException |
unsigned char get_dual_solution(lprec *lp, REAL *duals) | void getDualSolution(double[] duals) throws LpSolveException |
REAL get_epsb(lprec *lp) | double getEpsb() |
REAL get_epsd(lprec *lp) | double getEpsd() |
REAL get_epsel(lprec *lp) | double getEpsel() |
REAL get_epsint(lprec *lp) | double getEpsint() |
REAL get_epsperturb(lprec *lp) | double getEpsperturb() |
REAL get_epspivot(lprec *lp) | double getEpspivot() |
int get_improve(lprec *lp) | int getImprove() |
REAL get_infinite(lprec *lp) | double getInfinite() |
unsigned char get_lambda(lprec *lp, REAL *lambda) | void getLambda(double[] lambda) throws LpSolveException |
REAL get_lowbo(lprec *lp, int column) | double getLowbo(int colnr) throws LpSolveException |
int get_lp_index(lprec *lp, int orig_index) | int getLpIndex(int index) |
char *get_lp_name(lprec *lp) | String getLpName() throws LpSolveException |
int get_Lrows(lprec *lp) | int getLrows() |
REAL get_mat(lprec *lp, int row, int column) | double getMat(int row, int column) |
int get_max_level(lprec *lp) | int getMaxLevel() |
int get_maxpivot(lprec *lp) | int getMaxpivot() |
REAL get_mip_gap(lprec *lp, unsigned char absolute) | double getMipGap(boolean absolute) |
int get_Ncolumns(lprec *lp) | int getNcolumns() |
REAL get_negrange(lprec *lp) | double getNegrange() |
int get_nonzeros(lprec *lp) | int getNonzeros() |
int get_Norig_columns(lprec *lp) | int getNorigColumns() |
int get_Norig_rows(lprec *lp) | int getNorigRows() |
int get_Nrows(lprec *lp) | int getNrows() |
REAL get_obj_bound(lprec *lp) | double getObjBound() |
REAL get_objective(lprec *lp) | getObjective() |
int get_orig_index(lprec *lp, int lp_index) | int getOrigIndex(int index) |
char *get_origcol_name(lprec *lp, int column) | String getOrigcolName(int colnr) throws LpSolveException |
char *get_origrow_name(lprec *lp, int row) | String getOrigrowName(int rownr) throws LpSolveException |
int get_pivoting(lprec *lp) | int getPivoting() |
int get_presolve(lprec *lp) | int getPresolve() |
unsigned char get_primal_solution(lprec *lp, REAL *pv) | void getPrimalSolution(double[] pv) throws LpSolveException |
int get_print_sol(lprec *lp) | int getPrintSol() |
unsigned char get_ptr_constraints(lprec *lp, REAL **ptr_constr) | double[] getPtrConstraints() throws LpSolveException |
unsigned char get_ptr_dual_solution(lprec *lp, REAL **ptr_duals) | double[] getPtrDualSolution() throws LpSolveException |
unsigned char get_ptr_lambda(lprec *lp, REAL **ptr_lambda) | double[] getPtrLambda() throws LpSolveException |
unsigned char get_ptr_primal_solution(lprec *lp, REAL **ptr_pv) | double[] getPtrPrimalSolution() throws LpSolveException |
unsigned char get_ptr_sensitivity_obj(lprec *lp, REAL **ptr_objfrom, REAL **ptr_objtill) | double[][] getPtrSensitivityObj() throws LpSolveException |
unsigned char get_ptr_sensitivity_objex(lprec *lp, REAL **ptr_objfrom, REAL **ptr_objtill, REAL *ptr_objfromvalue, REAL *ptr_objtillvalue) | double[][] getPtrSensitivityObjex() throws LpSolveException |
unsigned char get_ptr_sensitivity_rhs(lprec *lp, REAL **ptr_duals, REAL **ptr_dualsfrom, REAL **ptr_dualstill) | double[][] getPtrSensitivityRhs() throws LpSolveException |
unsigned char get_ptr_variables(lprec *lp, REAL **ptr_var) | double[] getPtrVariables() throws LpSolveException |
REAL get_rh(lprec *lp, int row) | double getRh(int row) |
REAL get_rh_range(lprec *lp, int row) | double getRhRange(int rownr) throws LpSolveException |
unsigned char get_row(lprec *lp, int row_nr, REAL *row) | void getRow(int rownr, double[] row) throws LpSolveException |
<Not implemented> | double[] getPtrRow(int rownr) throws LpSolveException |
char *get_row_name(lprec *lp, int row) | String getRowName(int rownr) throws LpSolveException |
REAL get_scalelimit(lprec *lp) | double getScalelimit() |
int get_scaling(lprec *lp) | int getScaling() |
unsigned char get_sensitivity_obj(lprec *lp, REAL *objfrom, REAL *objtill) | void getSensitivityObj(double[] objfrom, double[] objtill) throws LpSolveException |
unsigned char get_sensitivity_objex(lprec *lp, REAL *objfrom, REAL *objtill, REAL *objfromvalue, REAL *objtillvalue) | void getSensitivityObjex(double[] objfrom, double[] objtill, double[] objfromvalue, double[] objtillvalue) throws LpSolveException |
unsigned char get_sensitivity_rhs(lprec *lp, REAL *duals, REAL *dualsfrom, REAL *dualstill) | void getSensitivityRhs(double[] duals, double[] dualsfrom, double[] dualstill) throws LpSolveException |
int get_simplextype(lprec *lp) | int getSimplextype() |
int get_solutioncount(lprec *lp) | int getSolutioncount() |
int get_solutionlimit(lprec *lp) | int getSolutionlimit() |
int get_status(lprec *lp) | int getStatus() |
char *get_statustext(lprec *lp, int statuscode) | String getStatustext(int statuscode) |
long get_timeout(lprec *lp) | long getTimeout() |
int get_total_iter(lprec *lp) | int getTotalIter() |
int get_total_nodes(lprec *lp) | int getTotalNodes() |
REAL get_upbo(lprec *lp, int column) | double getUpbo(int colnr) throws LpSolveException |
int get_var_branch(lprec *lp, int column) | int getVarBranch(int colnr) throws LpSolveException |
REAL get_var_dualresult(lprec *lp, int index) | double getVarDualresult(int index) throws LpSolveException |
REAL get_var_primalresult(lprec *lp, int index) | double getVarPrimalresult(int index) throws LpSolveException |
int get_var_priority(lprec *lp, int column) | int getVarPriority(int colnr) throws LpSolveException |
unsigned char get_variables(lprec *lp, REAL *var) | void getVariables(double[] var) throws LpSolveException |
int get_verbose(lprec *lp) | int getVerbose() |
REAL get_working_objective(lprec *lp) | double getWorkingObjective() throws LpSolveException |
unsigned char guess_basis(lprec *lp, double *guessvector, int *basisvector) | void guessBasis(double[] guessvector, int[] basisvector) throws LpSolveException |
unsigned char has_BFP(lprec *lp) | boolean hasBFP() |
unsigned char has_XLI(lprec *lp) | boolean hasXLI() |
unsigned char is_add_rowmode(lprec *lp) | boolean isAddRowmode() |
unsigned char is_anti_degen(lprec *lp, int testmask) | boolean isAntiDegen(int testmask) |
unsigned char is_binary(lprec *lp, int column) | boolean isBinary(int colnr) |
unsigned char is_break_at_first(lprec *lp) | boolean isBreakAtFirst() |
unsigned char is_constr_type(lprec *lp, int row, int mask) | boolean isConstrType(int row, int mask) |
unsigned char is_debug(lprec *lp) | boolean isDebug() |
unsigned char is_feasible(lprec *lp, REAL *values, REAL threshold) | boolean isFeasible(double[] values, double threshold) throws LpSolveException |
unsigned char is_free(lprec *lp, int column) | boolean isFree(int colnr) |
unsigned char is_infinite(lprec *lp, REAL value) | boolean isInfinite(double value) |
unsigned char is_int(lprec *lp, int column) | boolean isInt(int colnr) |
unsigned char is_integerscaling(lprec *lp) | boolean isIntegerscaling() |
unsigned char is_lag_trace(lprec *lp) | boolean isLagTrace() |
unsigned char is_maxim(lprec *lp) | boolean isMaxim() |
unsigned char is_nativeBFP(lprec *lp) | boolean isNativeBFP() |
unsigned char is_nativeXLI(lprec *lp) | boolean isNativeXLI() |
unsigned char is_negative(lprec *lp, int column) | boolean isNegative(int colnr) |
unsigned char is_piv_mode(lprec *lp, int testmask) | boolean isPivMode(int testmask) |
unsigned char is_piv_rule(lprec *lp, int rule) | boolean isPivRule(int rule) |
unsigned char is_presolve(lprec *lp, int testmask) | boolean isPresolve(int testmask) |
unsigned char is_scalemode(lprec *lp, int testmask) | boolean isScalemode(int testmask) |
unsigned char is_scaletype(lprec *lp, int scaletype) | boolean isScaletype(int scaletype) |
unsigned char is_semicont(lprec *lp, int column) | boolean isSemicont(int colnr) |
unsigned char is_SOS_var(lprec *lp, int column) | boolean isSOSVar(int colnr) throws LpSolveException |
unsigned char is_trace(lprec *lp) | boolean isTrace() |
int lag_solve(lprec *lp, REAL start_bound, int num_iter, short verbose) | <Function is currently not exported from lp_solve dll> |
void lp_solve_version(int *majorversion, int *minorversion, int *release, int *build) | static VersionInfo lpSolveVersion() |
lprec *make_lp(int rows, int columns) | static LpSolve makeLp(int rows, int columns) throws LpSolveException |
void print_constraints(lprec *lp, int columns) | void printConstraints(int columns) |
unsigned char print_debugdump(lprec *lp, char *filename) | void printDebugdump(String filename) throws LpSolveException |
void print_duals(lprec *lp) | void printDuals() |
void print_lp(lprec *lp) | void printLp() |
void print_objective(lprec *lp) | void printObjective() |
void print_scales(lprec *lp) | void printScales() |
void print_solution(lprec *lp, int columns) | void printSolution(int columns) |
void print_str(lprec *lp, char *str) | void printStr(String str) |
void print_tableau(lprec *lp) | void printTableau() |
void put_abortfunc(lprec *lp, ctrlcfunc newctrlc, void *ctrlchandle) | void putAbortfunc(AbortListener listener, Object userhandle) throws LpSolveException |
void put_logfunc(lprec *lp, logfunc newlog, void *loghandle) | void putLogfunc(LogListener listener, Object userhandle) throws LpSolveException |
void put_msgfunc(lprec *lp, msgfunc newmsg, void *msghandle, int mask) | void putMsgfunc(MsgListener listener, Object userhandle, int mask) throws LpSolveException |
lprec *read_freeMPS(char *filename, int verbose) | static LpSolve readFreeMps(String filename, int verbose) throws LpSolveException |
lprec *read_freemps(FILE *stream, int verbose) | <Not implemented, use readFreeMps instead> |
lprec *read_lp(FILE *stream, int verbose, char *lp_name) | <Not implemented, use readLp instead> |
lprec *read_LP(char *filename, int verbose, char *lp_name) | static LpSolve readLp(String filename, int verbose, String lpName) throws LpSolveException |
lprec *read_lpt(FILE *stream, int verbose, char *lp_name) | <Not implemented, use readLpt instead> |
lprec *read_LPT(char *filename, int verbose, char *lp_name) | static LpSolve readLpt(String filename, int verbose, String lpName) throws LpSolveException |
lprec *read_mps(FILE *stream, int verbose) | <Not implemented, use readMps instead> |
lprec *read_MPS(char *filename, int verbose) | static LpSolve readMps(String filename, int verbose) throws LpSolveException |
lprec *read_XLI(char *xliname, char *modelname, char *dataname, char *options, int verbose) | static LpSolve readXLI(String xliname, String modelname, String dataname, String options, int verbose) throws LpSolveException |
void reset_basis(lprec *lp) | void resetBasis() |
unsigned char resize_lp(lprec *lp, int rows, int columns) | void resizeLp(int rows, int columns) throws LpSolveException |
unsigned char set_add_rowmode(lprec *lp, unsigned char turnon) | boolean setAddRowmode(boolean turnon) |
void set_anti_degen(lprec *lp, int anti_degen) | void setAntiDegen(int antiDegen) |
unsigned char set_basis(lprec *lp, int *bascolumn, unsigned char nonbasic) | void setBasis(int[] bascolumn, boolean nonbasic) throws LpSolveException |
void set_basiscrash(lprec *lp, int mode) | void setBasiscrash(int mode) |
void set_bb_depthlimit(lprec *lp, int bb_maxlevel) | void setBbDepthlimit(int bbMaxlevel) |
void set_bb_floorfirst(lprec *lp, int bb_floorfirst) | void setBbFloorfirst(int floorFirst) |
void set_bb_rule(lprec *lp, int bb_rule) | void setBbRule(int bbRule) |
unsigned char set_BFP(lprec *lp, char *filename) | void setBFP(String filename) throws LpSolveException |
unsigned char set_XLI(lprec *lp, char *filename) | void setXLI(String filename) throws LpSolveException |
unsigned char set_binary(lprec *lp, int column, unsigned char must_be_bin) | void setBinary(int colnr, boolean mustBeBin) throws LpSolveException |
unsigned char set_bounds(lprec *lp, int column, REAL lower, REAL upper) | void setBounds(int colnr, double lower, double upper) throws LpSolveException |
void set_bounds_tighter(lprec *lp, unsigned char tighten) | void setBoundsTighter(boolean tighten) |
void set_break_at_first(lprec *lp, unsigned char break_at_first) | void setBreakAtFirst(boolean breakAtFirst) |
void set_break_at_value(lprec *lp, REAL break_at_value) | void setBreakAtValue(double breakAtValue) |
unsigned char set_col_name(lprec *lp, int column, char *new_name) | void setColName(int colnr, String name) throws LpSolveException |
unsigned char set_column(lprec *lp, int col_no, REAL *column) | void setColumn(int colno, double[] column) throws LpSolveException |
unsigned char set_columnex(lprec *lp, int col_no, int count, REAL *column, int *rowno) | void setColumnex(int colno, int count, double[] column, int[] rowno) throws LpSolveException |
unsigned char set_constr_type(lprec *lp, int row, int con_type) | void setConstrType(int rownr, int constrType) throws LpSolveException |
void set_debug(lprec *lp, unsigned char debug) | void setDebug(boolean debug) |
void set_epsb(lprec *lp, REAL epsb) | void setEpsb(double value) |
void set_epsd(lprec *lp, REAL epsd) | void setEpsd(double value) |
void set_epsel(lprec *lp, REAL epsel) | void setEpsel(double value) |
void set_epsint(lprec *lp, REAL epsint) | void setEpsint(double value) |
void set_epsperturb(lprec *lp, REAL epsperturb) | void setEpsperturb(double value) |
void set_epspivot(lprec *lp, REAL epspivot) | void setEpspivot(double value) |
unsigned char set_free(lprec *lp, int column) | void setFree(int colnr) throws LpSolveException |
void set_improve(lprec *lp, int improve) | void setImprove(int improve) |
void set_infinite(lprec *lp, REAL infinite) | void setInfinite(double value) |
unsigned char set_int(lprec *lp, int column, unsigned char must_be_int) | void setInt(int colnr, boolean mustBeInteger) throws LpSolveException |
void set_lag_trace(lprec *lp, unsigned char lag_trace) | void setLagTrace(boolean lagTrace) |
unsigned char set_lowbo(lprec *lp, int column, REAL value) | void setLowbo(int colnr, double value) throws LpSolveException |
unsigned char set_lp_name(lprec *lp, char *lpname) | void setLpName(String name) throws LpSolveException |
unsigned char set_mat(lprec *lp, int row, int column, REAL value) | void setMat(int row, int column, double value) throws LpSolveException |
void set_maxim(lprec *lp) | void setMaxim() |
void set_maxpivot(lprec *lp, int max_num_inv) | void setMaxpivot(int maxNumInv) |
void set_minim(lprec *lp) | void setMinim() |
void set_mip_gap(lprec *lp, unsigned char absolute, REAL mip_gap) | void setMipGap(boolean absolute, double value) |
void set_negrange(lprec *lp, REAL negrange) | void setNegrange(double negRange) |
void set_obj_bound(lprec *lp, REAL obj_bound) | void setObjBound(double objBound) |
unsigned char set_obj_fn(lprec *lp, REAL *row) | void setObjFn(double[] row) throws LpSolveException |
unsigned char set_obj_fnex(lprec *lp, int count, REAL *row, int *colno) | void setObjFnex(int count, double[] row, int[] colno) throws LpSolveException |
unsigned char set_obj(lprec *lp, int column, REAL value) | void setObj(int column, double value) throws LpSolveException |
void set_outputstream(lprec *lp, FILE *stream) | <Not implemented, use setOutputfile instead> |
unsigned char set_outputfile(lprec *lp, char *filename) | void setOutputfile(String filename) throws LpSolveException |
void set_pivoting(lprec *lp, int pivoting) | void setPivoting(int pivRule) |
void set_preferdual(lprec *lp, unsigned char dodual) | void setPreferdual(int dodual) |
void set_presolve(lprec *lp, int do_presolve) | void setPresolve(int doPresolve) |
void set_print_sol(lprec *lp, int print_sol) | void setPrintSol(int printSol) |
unsigned char set_rh(lprec *lp, int row, REAL value) | void setRh(int row, double value) throws LpSolveException |
unsigned char set_rh_range(lprec *lp, int row, REAL deltavalue) | void setRhRange(int rownr, double range) throws LpSolveException |
void set_rh_vec(lprec *lp, REAL *rh) | void setRhVec(double[] rh) throws LpSolveException |
unsigned char set_row(lprec *lp, int row_no, REAL *row) | void setRow(int rowno, double[] row) throws LpSolveException |
unsigned char set_rowex(lprec *lp, int row_no, int count, REAL *row, int *colno) | void setRowex(int rowno, int count, double[] row, int[] colno) throws LpSolveException |
unsigned char set_row_name(lprec *lp, int row, char *new_name) | void setRowName(int rownr, String name) throws LpSolveException |
void set_scalelimit(lprec *lp, REAL scalelimit) | void setScalelimit(double scalelimit) |
void set_scaling(lprec *lp, int scalemode) | void setScaling(int scalemode) |
unsigned char set_semicont(lprec *lp, int column, unsigned char must_be_sc) | void setSemicont(int colnr, boolean mustBeSc) throws LpSolveException |
void set_sense(lprec *lp, unsigned char maximize) | void setSense(boolean maximize) |
void set_simplextype(lprec *lp, int simplextype) | void setSimplextype(int simplextype) |
void set_solutionlimit(lprec *lp, int limit) | void setSolutionlimit(int limit) |
void set_timeout(lprec *lp, long sectimeout) | void setTimeout(long timeout) |
void set_trace(lprec *lp, unsigned char trace) | void setTrace(boolean trace) |
unsigned char set_upbo(lprec *lp, int column, REAL value) | void setUpbo(int colnr, double value) throws LpSolveException |
unsigned char set_var_branch(lprec *lp, int column, int branch_mode) | void setVarBranch(int colnr, int branchMode) throws LpSolveException |
unsigned char set_var_weights(lprec *lp, REAL *weights) | void setVarWeights(double[] weights) throws LpSolveException |
void set_verbose(lprec *lp, int verbose) | void setVerbose(int verbose) |
int solve(lprec *lp) | int solve() throws LpSolveException |
unsigned char str_add_column (lprec* lp, char* col_string) | void strAddColumn(String column) throws LpSolveException |
unsigned char str_add_constraint (lprec* lp, char *row_string, int constr_type, REAL rh) | void strAddConstraint(String row, int constrType, double rh) throws LpSolveException |
unsigned char str_add_lag_con (lprec* lp, char *row_string, int con_type, REAL rhs) | void strAddLagCon(String row, int constrType, double rh) throws LpSolveException |
unsigned char str_set_obj_fn(lprec *lp, char *row_string) | void strSetObjFn(String row) throws LpSolveException |
unsigned char str_set_rh_vec(lprec *lp, char *rh_string) | void strSetRhVec(String rh) throws LpSolveException |
REAL time_elapsed(lprec *lp) | double timeElapsed() |
void unscale(lprec *lp) | void unscale() |
unsigned char write_freeMPS(lprec *lp, FILE *stream) | <Not implemented, use writeFreeMps instead> |
unsigned char write_freemps(lprec *lp, char *filename) | void writeFreeMps(String filename) throws LpSolveException |
unsigned char write_lp(lprec *lp, char *filename) | void writeLp(String filename) throws LpSolveException |
unsigned char write_LP(lprec *lp, FILE *stream) | <Not implemented, use writeLp instead> |
unsigned char write_mps(lprec *lp, char *filename) | void writeMps(String filename) throws LpSolveException |
unsigned char write_MPS(lprec *lp, FILE *stream) | <Not implemented, use writeMps instead> |
unsigned char write_XLI(lprec *lp, char *filename, char *options, unsigned char results) | void writeXLI(String filename, String options, boolean results) throws LpSolveException |
lp_solve is a free (see LGPL for the GNU lesser general public license) linear (integer) programming solver based on the revised simplex method and the Branch-and-bound method for the integers. lp_solve has its own community via the Yahoo group http://groups.yahoo.com/group/lp_solve. There you can find the latest sources, executables for the common platforms, examples, manuals and a message board where people can share their thoughts on lp_solve.
lp_solve is written in ANSI C and can be compiled on many different platforms like Linux and Windows. Basically, lp_solve is a library, a set of routines, that can be called easily from programming languages like C, C++, C# and VB. Unfortunately, there is no simple and straightforward way to use native C libraries like lp_solve in Java programs. This library (also called "Java wrapper") is designed to remedy this shortcoming. It consists of two main parts:
LpSolve
class.This document should help you getting started using the Java wrapper and lp_solve in your
Java programs. Read it in addition to the documentation that comes with lp_solve.
Always refer to the lp_solve docs as ultimate reference for
using the routines of the optimization library.
Bug reports, succes stories and requests for changes concerning the Java wrapper are welcome
by email at juergen.ebert@web.de
or in the lp_solve discussion group.
The current wrapper version was written to work with lp_solve 5.5.0.9 and was tested under Windows XP and Linux. As long as the API stays the same, other versions of lp_solve are likely to work as well. The wrapper requires a Java Runtime Environment 1.3 or later.
The latest version of the Java wrapper can be found in the files section of the lp_solve group. The wrapper is released under the same LGPL license conditions as lp_solve. A copy of the LGPL text is contained in the distribution archive.
lp_solve_5.5_dev.(zip or tar.gz)
and lp_solve_5.5_exe.(zip or tar.gz)
to a standard library directory for your target platform.
On Windows, a typical place would be \WINDOWS
or \WINDOWS\SYSTEM32
.
On Linux, a typical place would be the directory /usr/local/lib
.
lpsolve55j.dll
to the directory that already contains lpsolve55.dll
.
liblpsolve55j.so
to the directory that already contains liblpsolve55.so
. Run ldconfig
to include
the library in the shared libray cache.
To create a Java application that uses lp_solve routines, you must perform the following steps:
lpsolve55j.jar
from the Java wrapper distribution to a
directory that is included in the CLASSPATH of your java program.lpsolve.*
at the beginning of your
source file.LpSolve.makeLp(...)
or one of the other static factory methods of the LpSolve
class to create a LpSolve
instance. Each LpSolve
instance represents an optimization
problem.LpSolve
instance to define the problem and obtain the solution.
Use the examples and implementation notes later in this documentation for further
information.lpsolve55j.jar
in the CLASSPATH.
Also, on Windows, if you installed the native stub library in a directory that is not included
in the PATH variable, you have to define the Java system variable java.library.path
which must point to the installation directory. On Linux, the equivalent of the Windows PATH
variable is called LD_LIBRARY_PATH.The following program is a very simple example that shows how to program with lp_solve in Java.
import lpsolve.*; public class Demo { public static void main(String[] args) { try { // Create a problem with 4 variables and 0 constraints LpSolve solver = LpSolve.makeLp(0, 4); // add constraints solver.strAddConstraint("3 2 2 1", LpSolve.LE, 4); solver.strAddConstraint("0 4 3 1", LpSolve.GE, 3); // set objective function solver.strSetObjFn("2 3 -2 3"); // solve the problem solver.solve(); // print solution System.out.println("Value of objective function: " + solver.getObjective()); double[] var = solver.getPtrVariables(); for (int i = 0; i < var.length; i++) { System.out.println("Value of var[" + i + "] = " + var[i]); } // delete the problem and free memory solver.deleteLp(); } catch (LpSolveException e) { e.printStackTrace(); } } }
The following code fragment shows you how to use callbacks in Java.
The example defines an anonymous inner class that implements the AbortListener
interface which is then passed to the putAbortfunc
method.
LpSolve solver = LpSolve.makeLp(0, 4); AbortListener abortfunc = new AbortListener() { public boolean abortfunc(LpSolve problem, Object handle) { System.out.println("Java abortfunc called, handle = " + handle); return false; } }; solver.putAbortfunc(abortfunc, new Integer(123));
Follow these steps to run the demo application, which is a port of the C demo program that comes with lp_solve to the Java language. You will need a Java Runtime Environment (JRE) on your machine in order to run the demo. You can download the latest JRE from http://java.sun.com
demo
directory and
start the batch script "run_demo.bat".demo
directory of the wrapper distribution and
run "sh run_demo".In the demo
directory you will find
the file LpSolveTest.java
which contains more than 100
JUnit test cases (see http://www.junit.org for
details about this highly useful software)
to strengthen the faith in the Java wrapper implementation. The test cases
may also seve as examples of basic lp_solve usage in Java. You will need
the library junit.jar
in your CLASSPATH
to run the test cases.
junit.jar
is included in the lib
directory of the Java wrapper. You
can run the test cases directly by starting the batch script "run_unittests.bat" on Windows
or "sh run_unittests" on Linux.
str_add_constraint
becomes strAddConstraint
in Java.lprec*
argument taken by almost all lp_solve API routines is hidden
completely inside the LpSolve
class. All methods that create new lprec
structures were made static methods of the LpSolve
class.set_row_name
returns FALSE if an error has occured. In Java,
setRowName
is of type void and throws a LpSolveException
.boolean
. Example:
set_debug(lprec *lp, unsigned char debug)
is setDebug(boolean debug)
in Java.
LpSolve
object, which represents a problem, is only used by one thread at a
time.get_ptr_sensitivity_rhs
, get_ptr_reduced_costs
,
get_ptr_sensitivity_obj
, and get_ptr_sensitivity_objex
are not implemented,
because it is not possible in Java to pass pointers by reference to a method. Use the corresponding
methods without the Ptr
part in the method name instead, which require allocation
of the resulting arrays by the caller.reference.html
for details on how the lp_solve API functions
are mapped to the Java methods.The Java wrapper archive contains precompiled binary libraries for Windows and Linux. If you just want to use the wrapper there should be no need to build the libs from the sources. But if you absolutely have to, follow the guidelines in this chapter.
lp_solve_5.5_dev.zip
unpackedlib/win32
directory and edit the file build.bat
.
Change the path to the directory where you unpacked the lp_solve Windows
archive. Run the script to build lpsolve55j.dll
.
lp_solve_5.5_dev.tar.gz
unpackedlib/linux
directory and edit the file build
.
Change the paths to the directory where you unpacked the lp_solve linux archive
and where the JDK is installed.
Run sh build
to build liblpsolve55j.so
.
Change to the lib/mac
directory and edit the file build_osx
.
Change the directory paths as indicated in the comments.
Thanks to Sean P. Kane (spkane@genomatica.com) who provided this build script.
Jython (http://www.jython.org) is a 100% Java implementation of the popular scripting language Python. One of the most remarkable features of Jython is the seamless interaction between Python and Java. Java programmers can add the Jython libraries to their system to allow end users to write scripts that add functionality to the application. On the other hand, Python/Jython programs can interact with Java packages or with running Java applications.
lp_solve functions can be called via the Java wrapper from Python/Jython programs.
See the file demo.py
in the demo
directory of the Java wrapper distribution
for an example program.
To run this program, you must install lp_solve, the Java wrapper, and Jython. Don't forget
to include lpsolve55j.jar
in the Java CLASSPATH when you run Jython.
get_scalingSpecifies which scaling algorithm is used. int get_scaling(lprec *lp); Return Value get_scaling returns which scaling algorithm is used. Can by any of the
following values:
Additionally, the value can be OR-ed with any combination of one of the following values:
Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The get_scaling function returns which scaling algorithm is used. This
can influence numerical stability considerably. It is advisable to always use
some sort of scaling. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_scaling, set_scalelimit, get_scalelimit, is_integerscaling, is_scalemode, is_scaletype |
LINDO lp filesThe LINDO LP file format provides a facility for entering a problem in a natural, algebraic LP formulation from the keyboard. The problem can be modified and saved from within lpsolve. This procedure is one way to create a file in a format that lpsolve can read. An alternative technique is to create a similar file using a standard text editor and to read it into lpsolve. The LINDO FILE format is provided as an input alternative to the MPS file format. An LP format file may be easier to generate than an MPS file if your problem already exists in an algebraic format or if you have an application that generates the problem file more readily in algebraic format (such as a C application). Note that the LINDO FILE format is not the same as the lpsolve LP format. See LP file format for a description about the native lpsolve lp format. To read/write this format from lpsolve, you need an XLI (see External Language Interfaces). The XLI for the LINDO format is called xli_LINDO. OptionsThe XLI accepts no options at this time. Examplelp_solve -rxli xli_LINDO input.lpt lp_solve -mps input.mps -wxli xli_LINDO output.lpt Syntax Rules of the LINDO FILE Formatlpsolve will accept any problem saved in an ASCII file provided that it adheres to the following syntax rules. The MPS file format is a column-oriented format. If a row-oriented format is more convenient, then the LINDO file format is of interest. The list of rules is rather short and easy to learn. Flow of ControlThe objective function must always be at the start of the model and is initiated with any of the following keywords:
The end of the objective function and the beginning of the constraints are signified with any of the following keywords:
The end of the constraints is signified with the word END. FormattingVariable names are limited to eight characters. Names must begin with an alphabetic character (A to Z), which may then be followed by up to seven additional characters. These additional characters may include anything with the exception of the following: ! ) + - = < >. As an example, the following names are valid:
whereas the following are not:
The first example contains more than eight characters, the second contains a forbidden hyphen, and the last example does not begin with an alphabetic character. You may, optionally, name constraints in a model. Constraint names must follow the same conventions as variable names. To name a constraint, you must start the constraint with its name terminated with a right parenthesis. After the right parenthesis, you enter the constraint as before. As an example, the following constraint is given the name XBOUND: XBOUND) X < 10 Only five operators are recognized: plus (+), minus (-), greater than (>), less than (<), and equals (=). When you enter the strict inequality operators greater than (>) and less than (<), they will be interpreted as the loose inequality operators greater-than-or-equal-to () and less-than-or-equal-to (), respectively. This is because many keyboards do not have the loose inequality operators. Even for systems having the loose operators, they will not be recognized. However, if you prefer, you may enter ">=" (and "<=") in place of ">" (and "<"). Parentheses as indicators of a preferred order of precedence are not accepted. All operations are ordered from left to right. Comments may be placed anywhere in a model. A comment is denoted by an exclamation mark. Anything following an exclamation mark on the current line will be considered a comment. For example: MAX 10 STD + 15 DLX ! Max profit SUBJECT TO ! Here are our factory capacity constraints ! for Standard and Deluxe computers STD < 10 DLX < 12 ! Here is the constraint on labor availability STD + 2 DLX < 16 END Comments are allowed, but they will not be stored with the model. Therefore, if later an equivalent model will be written, the comments will be removed. Constraints and the objective function may be split over multiple lines or combined on single lines. You may split a line anywhere except in the middle of a variable name or a coefficient. The following would be mathematically equivalent to our example (although not quite as easy to read): MAX 10 STD + 15 DLX SUBJECT TO STD < 10 DLX < 12 STD + 2 DLX < 16 END However, if the objective function appeared as follows: MAX 10 ST D + 1 5 DLX SUBJECT TO then an error would be returned because the variable STD is split between lines and the coefficient 15 is also. Only constant values--not variables--are permitted on the right-hand side of a constraint equation. Thus, an entry such as: X > Y would be rejected. Such an entry could be written as: X - Y > 0 Conversely, only variables and their coefficients are permitted on the left-hand side of constraints. For instance, the constraint: 3X + 4Y - 10 = 0 is not permitted because of the constant term of -10 on the left-hand side. The constraint may be recast as: 3X + 4Y = 10 By default, all variables have lower bounds of zero and upper bounds of infinity. Optional Modeling StatementsIn addition to the three required model components of an objective function, variables, and constraints, a number of other optional modeling statements may appear in a model following the END statement. These statements and their functions appear in the table below:
Next, we will briefly illustrate the use of each of these statements. FREE StatementThe default lower bound for a variable is 0. In other words, unless you specify otherwise, variables are not allowed to be negative. The FREE statement allows you to remove all bounds on a variable, so it may take on any real value, positive or negative. The following small example illustrates the use of the FREE statement: MIN 5X + Y ST X+Y>5 X-Y>7 END FREE Y Had we not set Y to be a free variable in this example, the optimal solution of X = 6 and Y = -1 would not have been found. Instead, given the default lower bound of 0 on Y, the solution X = 7 and Y = 0 would be returned. GIN StatementBy default, all variables are assumed to be continuous. In other words, unless told otherwise, variables are assumed to be any nonnegative fractional number. In many applications, fractional values may be of little use (e.g., 2.5 employees). In these instances, you will want to make use of the general integer statement, GIN. The GIN statement followed by a variable name restricts the value of the variable to the nonnegative integers (0,1,2,...). The following small example illustrates the use of the GIN statement: MAX 11X + 10Y ST 2X + Y < 12 X - 3Y > 1 END GIN X GIN Y Had we not specified X and Y to be general integers in this model, the optimal solution of X = 6 and Y = 0 would not have been found. Instead, X and Y would have been treated as continuous and returned the solution of X = 5.29 and Y = 1.43. Note also that simply rounding the continuous solution to the nearest integer values does not yield the optimal solution in this example. In general, rounded continuous solutions may be nonoptimal and, at worst, infeasible. Based on this, one can imagine that it can be very time consuming to obtain the optimal solution to a model with many integer variables. In general, this is true, and you are best off utilizing the GIN feature only when absolutely necessary. INT StatementUsing the INT statement restricts a variable to being either 0 or 1. These variables are often referred to as binary variables. In many applications, binary variables can be very useful in modeling all-or-nothing situations. Examples might include such things as taking on a fixed cost, building a new plant, or buying a minimum level of some resource to receive a quantity discount. The following small example illustrates the use of the INT statement: MAX -100X + 20A + 12B ST A - 10X < 0 A + B < 11 B < 7 END INT X !Make X 0/1 Had we not specified X to be binary in this example, a solution of X = .4, A = 4, and B = 7 for an objective value of 124 would not have been returned. Forcing X to be binary, you might guess that the optimal solution would be for X to be 0 because .4 is closer to 0 than it is to 1. If we round X to 0 and optimize for A and B, we get an objective of 84. In reality, a considerably better solution is obtained at X = 1, A = 10, and B = 1 for an objective of 112. In general, rounded continuous solutions may be nonoptimal and, at worst, infeasible. Based on this, one can imagine that it can be very time consuming to obtain the optimal solution to a model with many binary variables. In general, this is true and you are best off utilizing the INT feature only when absolutely necessary. SUB and SLB StatementsIf you do not specify otherwise, LINDO API assumes variables are continuous (bounded below by zero and unbounded from above). That is, variables can be any positive fractional number increasing indefinitely. In many applications, this assumption may not be realistic. Suppose your facilities limit the quantity produced of an item. In this case, the variable that represents the quantity produced is bounded from above. Or, suppose you want to allow for backordering in a system. An easy way to model this is to allow an inventory variable to go negative. In which case, you would like to circumvent the default lower bound of zero. The SUB and SLB statements are used to alter the bounds on a variable. SLB stands for Simple Lower Bound and is used to set lower bounds. Similarly, SUB stands for Simple Upper Bound and is used to set upper bounds. The following small example illustrates the use of the SUB and SLB: MAX 20X + 30Y ST X + 2Y < 120 END SLB X 20 SUB X 50 SLB Y 40 SUB Y 70 In this example, we could have just as easily used constraints to represent the bounds. Specifically, we could have entered our small model as follows: MAX 20X + 30X ST X + 2Y < 120 X > 20 X < 50 Y > 40 Y < 70 END This formulation would yield the same results, but there are two points to keep in mind. First, SUBs and SLBs are handled implicitly by the solver, and, therefore, are more efficient from a performance point of view than constraints. Secondly, SUBs and SLBs do not count against the constraint limit, allowing you to solve larger models within that limit. TITLE StatementThis statement is used to associate a title with a model. The title may be any alphanumeric string of up to 74 characters in length. Unlike all the other statements that must appear after the END statement, the TITLE statement may appear before the objective or after the END statement of a model. Here is an example of a small model with a title: TITLE Your Title Here MAX 20X + 30Y ST X < 50 Y < 60 X + 2Y < 120 END |
set_epselSpecifies the value that is used as a tolerance for rounding values to zero. void set_epsel(lprec *lp, REAL epsel); Return Value set_epsel has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI epsel The value that is used as a tolerance for rounding values to zero. Remarks The set_epsel function specifies the value that is used as a tolerance
for rounding values to zero. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_epsel, set_infinite, get_infinite, is_infinite, set_epsint, get_epsint, set_epsd, get_epsd, set_epsb, get_epsb, get_epspivot, set_epspivot, set_epsperturb, get_epsperturb, set_mip_gap, get_mip_gap |
DIMACS minimum cost flow problemsDIMACS (Center for Discrete Mathematics and Theoretical Computer Science (see http://dimacs.rutgers.edu/)) has formulated some 'challenges' for some specific problem instances (see http://dimacs.rutgers.edu/Challenges/). One of these challenges is network flows and matching - the first DIMACS implementation challenge. One of these network flows are minimum cost flow problems: Network Structure
There is a specific file format available for these kinds of problems: The DIMACS minimum-cost flow format requires that bounds on feasible arc flows be integer-valued (the LOW and CAP fields described below). All files contain only ASCII characters with information collected on each line, as described below. A line is terminated with an end-of-line character. Fields in each line are separated by at least one blank space. Each line begins with a one-character designator to identify the line type. The following information makes up a DIMACS minimum-cost flow input file:
As noted above, information is collected into lines, which begin with one-character designators. We describe each type of information line in turn.
Input File Example :The example network pictured here is followed by a corresponding DIMACS minimum-cost flow input file. Items listed in the lower-right of the graphic represent fields described above.
c This is a simple example file to demonstrate the DIMACS c input file format for minimum cost flow problems. The solution c vector is [2,2,2,0,4] with cost at 14. c c Problem line (nodes, links) p min 4 5 c c Node descriptor lines (supply+ or demand-) n 1 4 n 4 -4 c c Arc descriptor lines (from, to, minflow, maxflow, cost) a 1 2 0 4 2 a 1 3 0 2 2 a 2 3 0 2 1 a 2 4 0 3 3 a 3 4 0 5 1 c c End of file lp_solve can read/write and solve these models via the xli_DIMACS XLI driver (see External Language Interfaces).
It reads such a model in above format and solves it via linear programming.
The xli can also generate a DIMACS formatted file. lp_solve -rxli xli_DIMACS mincostflow.net This gives as result: Value of objective function: 14 Actual values of the variables: C1 2 C2 2 C3 2 C4 0 C5 4 Also from within the IDE, this XLI can be used. However, some entries must be added in LpSolveIDE.ini (in the folder where the IDE is installed). In the [XLI] section the following must be added: lib6=xli_DIMACS And a new section for the DIMACS XLI must also be added: [xli_DIMACS] extension=.net language=DIMACS Then make sure that the xli_DIMACS.dll is available for the IDE. This must be done by placing this dll in the IDE folder or in the Windows system32 folder. Solution :The solution vector of above example is [2, 2, 2, 0, 4] Output :The solution of the model can also be written in a DIMACS format:
For each network problem, the solution is an integer-valued flow assignment. The output file should list the solution and flow assignment for all arcs in the graph. As noted above, information is collected into lines, which begin with one-character designators. We describe each type of information line in turn.
lp_solve can generate a solution file via the xli_DIMACS XLI driver (see External Language Interfaces). lp_solve -rxli xli_DIMACS mincostflow.net -wxlisol xli_DIMACS mincostflow.sol This generates the following solution contents: c mincostflow.net c c Dimacs-format minimum cost flow result file c generated by lp_solve c c Solution s 14 c c SRC DST FLOW f 1 2 2 f 1 3 2 f 2 3 2 f 2 4 0 f 3 4 4 c c End of file lp_solve can also generate a solution file with only non-zero values. lp_solve -rxli xli_DIMACS mincostflow.net -wxlisol xli_DIMACS mincostflow.sol -wxlisolopt "-nz" This generates the following solution contents: c mincostflow.net c c Dimacs-format minimum cost flow result file c generated by lp_solve c c Solution s 14 c c Only non-zero flows are written c SRC DST FLOW f 1 2 2 f 1 3 2 f 2 3 2 f 3 4 4 c c End of file A testset of models can be found at http://elib.zib.de/pub/Packages/mp-testdata/mincost/ See Also DIMACS maximum flow problems, DIMACS assignment problems |
get_nameindexGets the index of a given column or row name in the lp. int get_nameindex(lprec *lp, char *name, unsigned char isrow); Return Value get_nameindex returns the index (column/row number) of the given column/row name. A return value of -1 indicates that the name does not exist. Note that the index is the original index number. So if presolve is active, it has no effect. It is the original column/row number that is returned. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI name The name of the column or row for which the index (column/row number) must be retrieved. isrow Set to FALSE (0) if column information is needed and TRUE (1) if row information is needed. Remarks The get_nameindex function returns the index (column/row number) of the given column/row name.
Note that this index starts from 1. Some API routines expect zero-based indexes and thus this value must then be corrected with -1. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_row_name, get_row_name, get_origrow_name, set_col_name, get_col_name, get_origcol_name |
get_rhGets the value of the right hand side (RHS) vector (column 0) for one row. REAL get_rh(lprec *lp, int row); Return Value
get_rh returns the value of the RHS for the specified row. If row is out
of range it returns 0. If no previous value was set, then it also returns 0,
the default RHS value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI row The row for which the RHS value must be retrieved. Must be between 0 and number of rows in the lp. value The value of the RHS. Remarks
The get_rh function returns the value of the RHS vector (column 0) for
the specified row. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_rh, set_rh_vec, str_set_rh_vec, add_constraint, add_constraintex, str_add_constraint, get_column, get_columnex, add_column, add_columnex, str_add_column, set_column, set_columnex, get_row, get_rowex, get_mat |
DIMACS maximum flow problemsDIMACS (Center for Discrete Mathematics and Theoretical Computer Science (see http://dimacs.rutgers.edu/)) has formulated some 'challenges' for some specific problem instances (see http://dimacs.rutgers.edu/Challenges/). One of these challenges is network flows and matching - the first DIMACS implementation challenge. One of these network flows are maximum flow problems: Network Structure
The following information makes up a DIMACS maximum flow input file:
As noted above, information is collected into lines, which begin with one-character designators. We describe each type of information line in turn.
Input File Example :The example network pictured here is followed by a corresponding DIMACS maximum flow input file.
c This is a simple example file to demonstrate the DIMACS c input file format for maximum flow problems. The solution c vector is [5,10,5,0,5,5,10,5] with cost at 15. c Problem line (nodes, links) p max 6 8 c source n 1 s c sink n 6 t c Arc descriptor lines (from, to, capacity) a 1 2 5 a 1 3 15 a 2 4 5 a 2 5 5 a 3 4 5 a 3 5 5 a 4 6 15 a 5 6 5 c c End of file lp_solve can read/write and solve these models via the xli_DIMACS XLI driver (see External Language Interfaces).
It reads such a model in above format and solves it via linear programming.
The xli can also generate a DIMACS formatted file. lp_solve -rxli xli_DIMACS maxflow.net This gives as result: Value of objective function: 45 Actual values of the variables: C1 5 C2 10 C3 5 C4 0 C5 5 C6 5 C7 10 C8 5 Also from within the IDE, this XLI can be used. However, some entries must be added in LpSolveIDE.ini (in the folder where the IDE is installed). In the [XLI] section the following must be added: lib6=xli_DIMACS And a new section for the DIMACS XLI must also be added: [xli_DIMACS] extension=.net language=DIMACS Then make sure that the xli_DIMACS.dll is available for the IDE. This must be done by placing this dll in the IDE folder or in the Windows system32 folder. Solution :The solution vector of above example is [5, 10, 5, 0, 5, 5, 10, 5] Output :The solution of the model can also be written in a DIMACS format:
For each network problem, the solution is an integer-valued flow assignment. The output file should list the solution and flow assignment for all arcs in the graph. As noted above, information is collected into lines, which begin with one-character designators. We describe each type of information line in turn.
lp_solve can generate a solution file via the xli_DIMACS XLI driver (see External Language Interfaces). lp_solve -rxli xli_DIMACS maxflow.net -wxlisol xli_DIMACS maxflow.sol This generates the following solution contents: c maxflow.net c c Dimacs-format maximum flow result file c generated by lp_solve c c Solution s 15 c c SRC DST FLOW f 1 2 5 f 1 3 10 f 2 4 5 f 2 5 0 f 3 4 5 f 3 5 5 f 4 6 10 f 5 6 5 c c End of file lp_solve can also generate a solution file with only non-zero values. lp_solve -rxli xli_DIMACS maxflow.net -wxlisol xli_DIMACS maxflow.sol -wxlisolopt "-nz" This generates the following solution contents: c maxflow.net c c Dimacs-format maximum flow result file c generated by lp_solve c c Solution s 15 c c Only non-zero flows are written c SRC DST FLOW f 1 2 5 f 1 3 10 f 2 4 5 f 3 4 5 f 3 5 5 f 4 6 10 f 5 6 5 c c End of file A testset of models can be found at the dimacs ftp site: ftp://dimacs.rutgers.edu/pub/netflow See Also DIMACS minimum cost flow problems, DIMACS assignment problems |
Introduction to lp_solve 5.5.0.13What is lp_solve and what is it not? The simple answer is, lp_solve is a Mixed Integer Linear Programming (MILP) solver. And what is Linear Programming? See "What is Linear Programming?" and "Oh, and we also want to solve it as an integer program." for a brief description. Also see Formulation of an lp problem in lpsolve. lp_solve is a free (see LGPL for the GNU lesser general public license)
linear (integer) programming solver based on the revised simplex method and the Branch-and-bound method
for the integers. lp_solve has its own community via the Yahoo group http://groups.yahoo.com/group/lp_solve/. There you can find the latest sources, executables for the common platforms, examples, manuals and a message board where people can share their thoughts on lp_solve. lp_solve was originally developed by Michel Berkelaar at Eindhoven University of Technology.
The work of Jeroen Dirks made the transition from the basic version 1.5 to the full version 2.0 possible.
He contributed the procedural interface, a built-in MPS reader, and many fixes and enhancements to the code.
At that point there was also a Java port of lp_solve 2.0. This was not a Java native interface (JNI) to the C
library, but rather a translation of the algorithm (ver 2.0) from C into Java. It was also very limited
This meant that it did not keep up with lp_solve as it evolved.
Starting at version 3.0, lp_solve is released under the LGPL license. Before the code could only be used for
non-commercial purposes. Many other people also contributed to lp_solve, but there was no track of them. Sorry
if you are not mentioned.
Development was stagnated for some time at version 3.2, but now it is again alive and well via the new
developers Kjell Eikland and Peter Notebaert.
But also other people help to improve the product.
For example the new Java interface to lp_solve was made by Juergen Ebert.
It is a JNI interface that supports the full functionality of lp_solve. He did a great job. We encourage other people to participate in the development of lp_solve. Basically, lp_solve is a library, a set of routines, called the API that can be called from almost any programming language to solve MILP problems. There are several ways to pass the data to the library:
Via the APIThe API is a set of routines that can be called from a programming language to build the model in memory, solve it and return the results. There are many API routines to perform many possible tasks and set several options. See lp_solve API reference for an overview.Via input filesStandard, lp_solve supports several input files types.
The common known MPS format (see mps-format) is supported by most solvers, but
it is not very readable for humans. Another format is the lp format (see lp-format)
that is more readable. lp_solve has the unique ability to use user-written routines to input the model
(see External Language Interface).
See read_mps, read_freemps, read_MPS, read_freeMPS and read_lp, read_LP for
the API calls to read the model from file. Via an IDEThanks to Henri Gourvest, there is now also an IDE program called LPSolve IDE that uses the API to provide a Windows application to solve models. See LPSolve IDE for its usage. With this program you don't have to know anything of API or computer programming languages. You can just provide your model to the program and it will solve the model and give you the result. As already stated, lp_solve can be called from many programming language. Among them are C, C++, Pascal, Delphi, Java, VB, C#, VB.NET, Excel. But let this list not be a limitation. Any programming language capable of calling external libraries (DLLs under Windows, Shared libraries (.so) under Unix/Linux) can call lp_solve. Here is a list of some key features of lp_solve:
|
add_SOSAdd a SOS (Special Ordered Sets) constraint. int add_SOS(lprec *lp, char *name, int sostype, int priority, int count, int *sosvars, REAL *weights); Return Value add_SOS returns the list index of the new SOS if the operation was successful. A return value of 0 indicates an error. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI name The name of the SOS constraint. sostype The type of the SOS constraint. Must be >= 1 priority Priority of the SOS constraint in the SOS set. count The number of variables in the SOS list. sosvars An array specifying the count variables (their column numbers). weights An array specifying the count variable weights. May also be NULL. In that case, lp_solve will weight the variables in the order they are specified. Remarks The add_SOS function adds an SOS constraint. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, is_SOS_var |
print_solutionPrints the solution (variables) of the lp. void print_solution(lprec *lp, int columns); Return Value print_solution has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI columns Number of columns to print solution. Remarks
The print_solution function prints the solution (variables) of the lp.
This can only be done after a successful solve. Example
See Also delete_lp, free_lp, make_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_variables, get_ptr_variables, print_lp, print_objective, print_constraints, print_duals, print_scales, print_tableau, print_str, set_outputstream, set_outputfile, print_debugdump |
write_paramsWrite settings to a parameter file. unsigned char write_params(lprec *lp, char *filename, char *options); Return Value Returns TRUE (1) if parameters could be written, else FALSE (0). Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI filename Filename to write the parameters to. options Optional options. Can be: Remarks All lp_solve parameters (options) are written to a parameter file. This file has an ini-format as used by Windows applications. All parameters are written under a header. This is by default [Default]. The header can be specified in the options parameter. Other headers are preserved. Example parameter file: [Default] ; lp_solve version 5.5 settings anti_degen=ANTIDEGEN_FIXEDVARS + ANTIDEGEN_STALLING + ANTIDEGEN_INFEASIBLE basiscrash=CRASH_NONE improve=IMPROVE_DUALFEAS + IMPROVE_THETAGAP maxpivot=250 negrange=-1e+006 pivoting=PRICER_DEVEX + PRICE_ADAPTIVE presolve=PRESOLVE_NONE presolveloops=2147483647 scalelimit=5 scaling=SCALE_GEOMETRIC + SCALE_EQUILIBRATE + SCALE_INTEGERS simplextype=SIMPLEX_DUAL_PRIMAL bb_depthlimit=-50 bb_floorfirst=BRANCH_AUTOMATIC bb_rule=NODE_PSEUDONONINTSELECT + NODE_GREEDYMODE + NODE_DYNAMICMODE + NODE_RCOSTFIXING ;break_at_first=0 ;break_at_value=-1e+030 mip_gap_abs=1e-011 mip_gap_rel=1e-011 epsint=1e-007 epsb=1e-010 epsd=1e-009 epsel=1e-012 epsperturb=1e-005 epspivot=2e-007 infinite=1e+030 ;debug=0 ;obj_bound=1e+030 ;print_sol=0 ;timeout=0 ;trace=0 ;verbose=NORMAL Note that there are some options commented out (;). This is done because these options can not be used in general for all models or because they are debug/trace/print options. These options can be made active and will be read by read_params but note again that they are possible dangerous to be used in general (except for the debug/trace/print options). Note that there are two kind of entries:
Numercial values can be integer values like maxpivot or floating point values like epsel Options are a combination of constants as defined in the manual. Multiple options are added with +. For example option anti_degen. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, read_params, reset_params |
is_maximReturns objective function direction. unsigned char is_maxim(lprec *lp); Return Value is_maxim returns a boolean value indicating if the objective direction is
maximize (TRUE) or minimize (FALSE). Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The default of lp_solve is to minimize, except for read_lp, read_LP where the default is to maximize. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_maxim, set_minim, set_sense |
set_row, set_rowexset a constraint in the lp. unsigned char set_row(lprec *lp, int row_no, REAL *row); unsigned char set_rowex(lprec *lp, int row_no, int count, REAL *row, int *colno); Return Value set_row, set_rowex return TRUE (1) if the operation was successful. A return value of FALSE (0) indicates an error. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI row_no The row number that must be changed. count Number of elements in row and colno. row An array with 1+get_Ncolumns (count for set_rowex, if colno is different from NULL) elements that contains the values of the row. colno A zero-based array with count elements that contains the column numbers of the row. However this variable can also be NULL. In that case element i in the variable row is column i and values start at element 1. Remarks The set_row, set_rowex functions change the values of an existing row in the
model at once. Example
See Also make_lp, copy_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_row, get_rowex, add_constraint, add_constraintex, str_add_constraint, set_obj_fn, set_obj_fnex, str_set_obj_fn, set_obj, set_add_rowmode, is_add_rowmode, get_constr_type, is_constr_type, del_constraint, add_column, add_columnex, str_add_column, set_column, set_columnex, get_column, get_columnex, get_mat |
write_lp, write_LP, write_lpexWrite an lp model to a file or via a routine. unsigned char write_LP(lprec *lp, FILE *stream); unsigned char write_lp(lprec *lp, char *filename); unsigned char write_lpex(lprec *lp, void *userhandle, (void *userhandle, char *buf) write_modeldata_routine); Return Value
The routines return TRUE (1) if the operation was
successful. A return value of FALSE (0) indicates an error. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI stream Pointer to FILE structure. filename Filename to write the lp model to. write_modeldata_routine
Routine to write the lp model to. The routine has following definition: Remarks The write_lp and write_LP functions write the model to filename. write_LP needs a file pointer to an already opened file. write_lp accepts the name of the file. The latter function will generally be more convenient. write_lpex writes the model via a user defined routine. When stream or filename are NULL, then output is written to output set by set_outputstream, set_outputfile. By default this is stdout.The model in the file will be in lp-format. Example
See Also delete_lp, free_lp, make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, write_mps, write_freemps, write_MPS, write_freeMPS, MPS_writefileex |
is_constr_typeReturns if constraint type specified in mask is active. unsigned char is_constr_type(lprec *lp, int row, int mask); Return Value is_constr_type returns TRUE or FALSE Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI row The row for which the constraint type must be retrieved. Must be between 1 and number of rows in the lp. mask Any of the following values:
Remarks The is_constr_type function returns a flag if constraint type specified in mask is active. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_constr_type, set_constr_type, add_constraint, add_constraintex, str_add_constraint, del_constraint |
is_feasibleChecks if provided solution is a feasible solution. unsigned char is_feasible(lprec *lp, REAL *values, REAL threshold); Return Value is_feasible returns FALSE (0) or TRUE (1) that indicates if provided
solution is feasible. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI values An array of row/column values that are checked against the bounds
and ranges. threshold A tolerance value. The values may differ that much. Recommended to use get_epsint for this value. Remarks The is_feasible function checks if provided solution is a feasible
solution. All values of the values array must be between the bounds and
ranges to be a feasible solution. Example
See Also make_lp, copy_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_objective, get_working_objective, get_variables, get_ptr_variables, get_constraints, get_ptr_constraints, get_constr_value, get_primal_solution, get_ptr_primal_solution, get_var_primalresult, get_sensitivity_rhs, get_ptr_sensitivity_rhs, get_dual_solution, get_ptr_dual_solution, get_var_dualresult, get_sensitivity_obj, get_ptr_sensitivity_obj, get_sensitivity_objex, get_ptr_sensitivity_objex |
set_obj_in_basisSpecifies if the objective is in the matrix or not. void set_obj_in_basis(lprec *lp, unsigned char obj_in_basis); Return Value set_obj_in_basis has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI obj_in_basis TRUE or FALSE. Objective is in matrix or not. Remarks The set_obj_in_basis function specifies if the objective is in the matrix or not. By default, the objective function is stored as the top row in the constraint matrix When this function is called with obj_in_basis = FALSE then it is moved out into separate storage. When out of the basis, the computation of reduced costs is somewhat slower. In the late versions of v5.5, there is now the option to calculate reduced cost in the textbook way, i.e. completely independently of the basis. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, is_obj_in_basis |
set_solutionlimitSets the solution number that must be returned. void set_solutionlimit(lprec *lp, int limit); Return Value set_solutionlimit has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI limit The solution number that must be returned. This value gives the number of the solution that must be returned. Remarks This function is only valid if there are integer, semi-continious or SOS variables in the model so that the branch-and-bound algoritm is used. If there are more solutions with the same objective value, then this number specifies which solution must be returned. This can be used to retrieve all possible solutions. Start with 1 till get_solutioncount Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_solutionlimit, get_solutioncount |
get_solutioncountReturns the number of equal solutions. int get_solutioncount(lprec *lp); Return Value get_solutioncount returns the number of equal solutions. This is only valid if there are integer, semi-continious or SOS variables in the model so that the branch-and-bound algoritm is used. This count gives the number of solutions with the same optimal objective value. If there is only one optimal solution, this value is 1. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The get_solutioncount function returns the number of equal solutions up to get_solutionlimit. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_solutionlimit, set_solutionlimit |
get_statustextReturns the description of a returncode of the solve function. char *get_statustext(lprec *lp, int statuscode); Return Value The description of a returncode of the solve function Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI statuscode Returncode of solve Remarks The get_statustext function returns a comprehensible description of a returncode of the solve function. Example
See Also free_lp, make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, solve |
print_constraintsPrints the values of the constraints of the lp. void print_constraints(lprec *lp, int columns); Return Value print_constraints has no return value. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI columns Number of columns to print solution. Remarks
The print_constraints function prints the values of the constraints of the lp.
This can only be done after a successful solve. Example
See Also delete_lp, free_lp, make_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_constraints, get_constr_value, print_lp, print_objective, print_solution, print_duals, print_scales, print_tableau, print_str, set_outputstream, set_outputfile, print_debugdump |
write_basisWrites current basis to a file. unsigned char write_basis(lprec *lp, char *filename); Return Value Returns TRUE if basis could be written to filename and FALSE if not. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI filename Filename to write the basis to. Remarks
The write_basis function writes the current basis to filename. The basis in the file is written in MPS bas file format. When filename is NULL, then output is written to output set by set_outputstream, set_outputfile. By default this is stdout. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, get_basis, set_basis, default_basis, read_basis, guess_basis, get_basiscrash, set_basiscrash |
set_matSet a single element in the matrix. unsigned char set_mat(lprec *lp, int row, int column, REAL value); Return Value
set_mat returns TRUE (1) if the operation was successful. A return value
of FALSE (0) indicates an error. Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI row Row number of the matrix. Must be between 0 and number of rows in the lp. Row 0 is objective function. column Column number of the matrix. Must be between 1 and number of columns in the lp. value Value to be set for row row, column column. Remarks
The set_mat function sets a value in the matrix. If there was already a
value for this element, it is replaced and if there was no value, it is added. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, add_constraint, add_constraintex, str_add_constraint, set_row, set_rowex, set_obj_fn, set_obj_fnex, str_set_obj_fn, add_column, add_columnex, str_add_column, set_column, set_columnex, get_column, get_columnex, get_row, get_rowex, get_mat |
get_verboseReturns the verbose level. int get_verbose(lprec *lp); Return Value get_verbose returns the current verbose level. Can be one of the following values:
Parameters lp Pointer to previously created lp model. See return value of make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI Remarks The get_verbose function returns the verbose level. Example
See Also make_lp, copy_lp, read_lp, read_LP, read_mps, read_freemps, read_MPS, read_freeMPS, read_XLI, set_verbose, put_logfunc |