> Tutorials > Concert Technology Tutorial for C++ Users > Building and Solving a Small LP Model in C++ |
Building and Solving a Small LP Model in C++ |
INDEX
![]() |
A complete example of building and solving a small LP model can now be presented. This example demonstrates:
Example ilolpex1.cpp
, which is one of the example programs in the standard ILOG CPLEX distribution, is an extension of the example presented in Introducing ILOG CPLEX. It shows three different ways of creating an ILOG Concert Technology LP model, how to solve it using IloCplex
, and how to access the solution. Here is the problem that the example optimizes:
Maximize |
x1 + 2x2 + 3x3 |
subject to |
-x1 + x2 + x3 ![]()
x1 - 3x2 + x3 ![]() |
with these bounds |
0 ![]() ![]()
0 ![]() ![]() ![]()
0 ![]() ![]() ![]() |
The first operation is to create the environment object env
, and the last operation is to destroy it by calling env.end
. The rest of the code is enclosed in a try/catch
clause to gracefully handle any errors that may occur.
First the example creates the model object and, after checking the correctness of command line parameters, it creates empty arrays for storing the variables and range constraints of the optimization model. Then, depending on the command line parameter, the example calls one of the functions populatebyrow
, populatebycolumn
, or populatebynonzero
, to fill the model object with a representation of the optimization problem. These functions return the variable and range objects in the arrays var
and con
which are passed to them as parameters.
After the model has been populated, the IloCplex
algorithm object cplex
is created and the model is extracted to it. The following call of the method solve
invokes the optimizer. If it fails to generate a solution, an error message is issued to the error stream of the environment, cplex.error()
, and the integer -1 is thrown as an exception.
IloCplex
provides the output streams out
for general logging, warning
for warning messages, and error
for error messages. They are preconfigured to cout
, cerr
, and cerr
respectively. Thus by default you will see logging output on the screen when invoking the method solve
. This can be turned off by calling cplex.setOut(env.getNullStream())
, that is, by redirecting the out
stream of the IloCplex
object cplex
to the null stream of the environment.
If a solution is found, solution information is output through the channel, env.out
which is initialized to cout
by default. The output operator <<
is defined for type IloAlgorithm::Status
as returned by the call to cplex.getStatus
. It is also defined for IloNumArray
, the ILOG Concert Technology class for an array of numerical values, as returned by the calls to cplex.getValues
, cplex.getDuals
, cplex.getSlacks
, and cplex.getReducedCosts
. In general, the output operator is defined for any ILOG Concert Technology array of elements if the output operator is defined for the elements.
The functions named populateby
* are purely about modeling and are completely decoupled from the algorithm IloCplex
. In fact, they don't use the cplex
object, which is created only after executing one of these functions.
The function populatebyrow
creates the variables and adds them to the array x
. Then the objective function and the constraints are created using expressions over the variables stored in x
. The range constraints are also added to the array of constraints c
. The objective and the constraints are added to the model.
Function populatebycolumn
can be viewed as the transpose of populatebyrow
. While for simple examples like this one population by rows may seem the most straightforward and natural approach, there are some models where modeling by column is a more natural or more efficient approach.
When modeling by columns, range objects are created with their lower and upper bound only. No expression is given—which is impossible since the variables are not yet created. Similarly, the objective function is created with only its intended optimization sense, and without any expression. Next the variables are created and installed in the already existing ranges and objective.
The description of how the newly created variables are to be installed in the ranges and objective is by means of column expressions, which are represented by the class IloNumColumn
. Column expressions consist of objects of class IloAddNumVar
linked together with operator +
. These IloAddNumVar
objects are created using operator()
of the classes IloObjective
and IloRange
. They define how to install a new variable to the invoking objective or range objects. For example, obj(1.0)
creates an IloAddNumVar
capable of adding a new modeling variable with a linear coefficient of 1.0 to the expression in obj
. Column expressions can be built in loops using operator +=
.
Column expressions (objects of class IloNumColumn
) are handle objects, like most other Concert Technology objects. The method end
must therefore be called to delete the associated implementation object when it is no longer needed. However, for implicit column expressions, where no IloNumColumn
object is explicitly created, such as the ones used in this example, the method end
should not be called.
The column expression is passed as a parameter to the constructor of class IloNumVar
. For example the constructor IloNumVar(obj(1.0) + c[0](-1.0) + c[1]( 1.0), 0.0, 40.0)
creates a new modeling variable with lower bound 0.0, upper bound 40.0 and, by default, type ILOFLOAT
, and adds it to the objective obj
with a linear coefficient of 1.0, to the range c[0]
with a linear coefficient of -1.0 and to c[1]
with a linear coefficient of 1.0. Column expressions can be used directly to construct numerical variables with default bounds [0, IloInfinity]
and type ILOFLOAT
, as in the following statement:
where IloNumVar
does not need to be explicitly written. Here, the C++ compiler recognizes that an IloNumVar
object needs to be passed to the add
method and therefore automatically calls the constructor IloNumVar(IloNumColumn)
in order to create the variable from the column expression.
The last of the three functions that can be used to build the model is populatebynonzero
. It creates objects for the objective and the ranges without expressions, and variables without columns. Then methods IloObjective::setCoef
and IloRange::setCoef
are used to set individual nonzero values in the expression of the objective and the range constraints. As usual, the objective and ranges must be added to the model.
The complete program follows. You can also view it online in the file ilolpex1.cpp
.
Copyright © 1987-2003 ILOG, S.A. All rights reserved. Legal terms. | PREVIOUS NEXT |