CPLEX Concert Technology using C++
A Tutorial
Prepared by:
Manish Bansal
Kiavash Kianfar
April 2013
Version 1.0
1
Contents
1 CPLEX Concert Technology: An Introduction 3
2 Access to CPLEX 3
3 Setting up CPLEX Concert with C++ on Windows in Release Mode 4
4 Setting up CPLEX Concert with C++ on Windows in Debug Mode 6
5 Solving an IP with CPLEX Concert Technology using C++ 8
6 Compiling an example to test installation 9
7 Basic Programming Tips 9
8 Example: Multiperiod Production Model 14
9 Advanced Programming Tips [1] 17
9.1 Accessing solution information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
9.2 Import data from .mps, .lp, or .sav file . . . . . . . . . . . . . . . . . . . . . . . . 19
9.3 Modifying an optimization problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
9.4 Output messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
9.5 Debugging (handling error) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
10 Setting CPLEX parameters 20
References 20
2
1. CPLEX Concert Technology: An Introduction
ILOG CPLEX Optimizer is a tool that offers libraries to solve various optimization problems
including linear programs (LPs), and mixed integer programs (MIPs). In order to meet a wide
range of users’ requirement, CPLEX comes in following forms:
• The CPLEX Interactive Optimizer is an executable program that can read a problem inter-
actively or from files in certain standard formats, solve the problem, and deliver the solution
interactively or into text files.
• Concert Technology is a set of libraries that allow a programmer to embed CPLEX optimizers
in C++, Java, or .NET applications.
• The CPLEX Callable Library is a C library that allows the programmer to embed CPLEX
optimizers in applications written in C, Visual Basic, Fortran or any other language that can
call C functions.
• The Python API for CPLEX a full-featured Python application programming interface sup-
porting all aspects of CPLEX optimization.
• The CPLEX connector for The MathWorks MATLAB enables a user to define optimization
problems and solve them within MATLAB using either the MATLAB Toolbox or a CPLEX
class in the MATLAB language
This tutorial focuses on modeling and solving LPs and MIPs using CPLEX Concert Technology in
C++. Some sections of this tutorial are based on ILOG CPLEX Reference Manuals [1]. It should
be noted that ILOG CPLEX has many more features which can be learned by referring to [1].
2. Access to CPLEX
• ISEN Lab (ETB 3005) provides access to CPLEX12.2 if you have an ISEN account. In
case, you don’t have the account then please contact the help desk in ETB 3005 to get one.
After logging-in to an ISEN system, perform steps mentioned in Section 4.
• ISEN Lab (Cloud Computing) provides virtual access to ISEN lab computer and soft-
wares, if you have an ISEN account. Log-in to https://isegoapps.tamu.edu to use CPLEX
Concert Technology with Microsoft Visual C++ 2008, or visit https://isegodesk.tamu.edu
to have desktop environment.
• Personal Computer : IBM provides full-version IBM ILOG CPLEX Optimization Studio
via IBM’s Academic Initiative program, which provides no-charge access to full-version soft-
ware and professionally developed courseware for graduate assistants who is teaching or doing
research [2, 3]. They also provide a 90 days trial access to IBM ILOG CPLEX Optimization
Studio Preview Edition V12.5 for Windows. For more details and to download the software
click http://www-03.ibm.com/ibm/university/academic/pub/page/mem_join. Then, reg-
ister for a universal IBM ID and follow the steps mentioned on the site. After installing the
software on your personal computer, perform steps mentioned in Section 4.
3
Remark: Throughout this document, the Concert Technology installation folder is referred
to as , and the CPLEX installation folder is referred to as . If you
are accessing CPLEX from ISEN lab then represents J:\CPLEX12x64\ILOG\
Concert29, and represents J:\CPLEX12x64\ILOG\CPLEX121. While if you have
installed the CPLEX in folder, say for example, C:\ILOG\CPLEX, references to \
include represents C:\ILOG\CPLEX\concert\include.
3. Setting up CPLEX Concert with C++ on Windows in Release
Mode
To use IBM ILOG CPLEX with Microsoft Visual C++, first consult the file c_cpp.html available
in the folder . Then follow the directions you find there. The information below
applies to the Visual C++ 2008 multi-threaded STL library. If you use another version of the
library, set the Runtime Library option to match the library version. If you use Visual Studio
2010, the instructions below should apply, except that x64_windows_vs2008 should be replaced
with x64_windows_vs2010 whenever a path name is specified. It is important to remember that
CPLEX Concert Technology using ISEN lab systems cannot be linked to Visual C++ 2010.
Step I. Create a Project Workspace in MS Visual Studio 2008
(a) (Re)Start Microsoft Visual Studio 2008.
(b) From the File menu, select New, and then New Project.
(c) The New Project dialog box appears.
(d) In the Project Types pane, select Visual C++ Projects.
(e) In the Templates pane, select the Win32 Project icon.
(f) Fill in the project name, .
(g) If necessary, correct the location of the project (to )
(h) Click OK
(i) When the Win32 Application Wizard appears, click on Application Settings.
(j) Select Console Application as Application type.
(k) Make sure that Empty project is checked in Additional Options.
(l) Click Finish.
(m) Right Click on the Project Name in the Project Tree, choose Add New Item.
(n) Select C++ File (.cpp). Enter a valid file name and appropriate path.
(o) Click Open.
Step II. Link CPLEX and Concert libraries to the properties of your project in Visual Studio
2008
(a) From the Project menu, choose Properties.
(b) The Property Pages dialog box appears.
(c) In the Configuration drop-down list, select Release.
(d) Select C/C++ in the Configuration Properties tree.
4
• Select General:
– In the Additional Include Directories field, add the directories:
\include, \include.
– For Debug Information Format, choose Disabled.
– Choose No for Detect 64-bit Portability Issues.
• Select Preprocessor: Add IL_STD to the Preprocessor Definitions field. This
defines the macro IL_STD which is needed to use the STL.
• Select Code Generation: Set Runtime Library to Multi-threaded (/MT).
(e) Select Linker in the Configuration Properties tree. Select Input and then select
Additional Dependencies. Add the files:
wsock32.lib
\lib\x64_windows_vs2008\stat_mta\cplex121.lib
\lib\x64_windows_vs2008\stat_mta\ilocplex.lib
\lib\x64_windows_vs2008\stat_mta\concert.lib
The latter two are necessary while using Concert Technology.
(f) Click OK to close the Property Pages dialog box.
(g) Next, you have to set the default project configuration. From the Build menu, select
Configuration Manager.
(h) Select Release in the Active Solution Configuration drop-down list.
(i) Under Active Solution Platform, choose New.
(j) Type x64 for the new platform.
(k) Choose copy settings from Win32.
(l) Click OK.
(m) Click Close.
Step III. Add CPLEX DLL to the environment variable
Either go to \bin\x64_win64 and copy the file cplex121.dll to folder
\\, or do the following steps:
(a) From the Start menu, select Control Panel.
(b) In the Control Panel, select System.
(c) In the System dialog, select the Advanced tab.
(d) On the Advanced tab, click the Environment Variables button.
(e) Add or extend the PATH environment variable. If the PATH environment variable
already exists, extend it, like this:
Name: PATH
Value: \bin\x64_win64
(f) Restart Visual Studio for this change in the operating system to take effect.
5
4. Setting up CPLEX Concert with C++ on Windows in Debug
Mode
The Visual C++ run-time library with debug settings detects incorrect iterator use, and asserts
and displays a dialog box at run time. To enable debug iterator support, you must use a debug
version of a C++ run-time library to compile your program. From the Concert point of view, the
only difference between the Win32 Release and Win32 Debug targets is:
• the NDEBUG macro is defined for the Win32 Release target.
• the NDEBUG macro is not defined for the Win32 Debug target.
This is why we have suggested using Win32 Release in the examples, even though it is not the default
proposed by Visual C++. Refer to the Visual C++ Reference Manual for full information on Win32
Release and Win32 Debug. The interaction of the NDEBUG macro and the Concert inline member
functions is documented in the ILOG Concert Technology Reference Manual. The information
below applies to the Visual C++ 2008 multi-threaded STL library. If you use another version of
the library, set the Runtime Library option to match the library version. If you use Visual Studio
2010, the instructions below should apply, except that x64_windows_vs2008 should be replaced
with x64_windows_vs2010 whenever a path name is specified. It is important to remember that
CPLEX Concert Technology using ISEN lab systems cannot be linked to Visual C++ 2010.
Step I. Create a Project Workspace in MS Visual Studio 2008
(a) (Re)Start Microsoft Visual Studio 2008.
(b) From the File menu, select New, and then New Project.
(c) The New Project dialog box appears.
(d) In the Project Types pane, select Visual C++ Projects.
(e) In the Templates pane, select the Win32 Project icon.
(f) Fill in the project name, .
(g) If necessary, correct the location of the project (to )
(h) Click OK
(i) When the Win32 Application Wizard appears, click on Application Settings.
(j) Select Console Application as Application type.
(k) Make sure that Empty project is checked in Additional Options.
(l) Click Finish.
(m) Right Click on the Project Name in the Project Tree, choose Add New Item.
(n) Select C++ File (.cpp). Enter a valid file name and appropriate path.
(o) Click Open.
Step II. Link CPLEX and Concert libraries to the properties of your project in Visual Studio
2008
(a) From the Project menu, choose Properties.
(b) The Property Pages dialog box appears.
6
(c) In the Configuration drop-down list, select Debug.
(d) Select C/C++ in the Configuration Properties tree.
• Select General:
– In the Additional Include Directories field, add the directories:
\include, \include.
– For Debug Information Format, choose Program Database (/Zi).
– Choose No for Detect 64-bit Portability Issues.
• Select Optimization: Select Disabled (/Od) for optimization
• Select Preprocessor: Add WIN32, NDEBUG, _CONSOLE, and IL_STD to the Pre-
processor Definitions field.
• Select Code Generation: Set Runtime Library to Multi-threaded (/MT).
(e) Select Linker in the Configuration Properties tree.
• Select Input and then select Additional Dependencies. Add the files:
wsock32.lib
\lib\x64_windows_vs2008\stat_mta\cplex121.lib
\lib\x64_windows_vs2008\stat_mta\ilocplex.lib
\lib\x64_windows_vs2008\stat_mta\concert.lib
The latter two are necessary while using Concert Technology.
• Select Debugging and then in the Generate Debug Info field, select /DEBUG.
(f) Click OK to close the Property Pages dialog box.
(g) Next, you have to set the default project configuration. From the Build menu, select
Configuration Manager.
(h) Select Debug in the Active Solution Configuration drop-down list.
(i) Under Active Solution Platform, choose New.
(j) Type x64 for the new platform.
(k) Choose copy settings from Win32.
(l) Click OK.
(m) Click Close.
Step III. Add CPLEX DLL to the environment variable
Either go to \bin\x64_win64 and copy the file cplex121.dll to folder
\\, or do the following steps:
(a) From the Start menu, select Control Panel.
(b) In the Control Panel, select System.
(c) In the System dialog, select the Advanced tab.
(d) On the Advanced tab, click the Environment Variables button.
(e) Add or extend the PATH environment variable. If the PATH environment variable
already exists, extend it, like this:
Name: PATH
Value: \bin\x64_win64
(f) Restart Visual Studio for this change in the operating system to take effect.
7
5. Solving an IP with CPLEX Concert Technology using C++
In this section, we briefly demostrate how to create and solve an integer program (and its LP
relaxation). To do so, we consider the Example 1.1 of the book: Integer Programming by Laurance
A. Wolsey. The integer program is given as follows:
max 1.00x1 + 0.64x2 (1)
s.t. 50x1 + 31x2 ≤ 250 (2)
3x1 − 2x2 ≥ −4 (3)
x1, x2 ∈ Z+. (4)
Below is a C++ code using CPLEX in Concert Technology to solve this integer program and its
LP relaxation, i.e. x1, x2 ∈ R+.
#include < i l c p l e x / i l o c p l e x . h>
ILOSTLBEGIN
stat ic void
populatebyrow ( I loModel model , IloNumVarArray var , I loRangeArray con ) ;
int main (void ) {
I loEnv env ;
try {
I loModel model ( env ) ;
IloNumVarArray var ( env ) ;
I loRangeArray con ( env ) ;
populatebyrow (model , var , con ) ;
I l oCplex cp lex (model ) ;
cp l ex . s o l v e ( ) ;
env . out ( ) << ” So lu t i on s t a tu s = ” << cp lex . ge tStatus ( ) << endl ;
env . out ( ) << ” So lu t i on value = ” << cp lex . getObjValue ( ) << endl ;
IloNumArray va l s ( env ) ;
cp l ex . getValues ( va l s , var ) ;
env . out ( ) << ”Values = ” << va l s << endl ;
cp l ex . g e tS l a ck s ( va l s , con ) ;
env . out ( ) << ” S lacks = ” << va l s << endl ;
cp l ex . exportModel ( ” ipex1 . lp ” ) ;
}
catch ( I l oExcept i on& e ) {
c e r r << ”Concert except ion caught : ” << e << endl ;
}
catch ( . . . ) {
c e r r << ”Unknown except ion caught” << endl ;
}
env . end ( ) ;
return 0 ;
} // END main
stat ic void
populatebyrow ( I loModel model , IloNumVarArray x , IloRangeArray c ){
I loEnv env = model . getEnv ( ) ;
8
x . add ( IloNumVar ( env , 0 . 0 , I l o I n f i n i t y , ILOINT ) ) ;
x . add ( IloNumVar ( env , 0 . 0 , I l o I n f i n i t y , ILOINT ) ) ;
model . add ( I loMaximize ( env , 1 .00 ∗ x [ 0 ] + 0 .64 ∗ x [ 1 ] ) ) ;
c . add ( 50 ∗ x [ 0 ] + 31 ∗ x [ 1 ] <= 250) ;
c . add ( 3 ∗ x [ 0 ] − 2 ∗ x [ 1 ] >= −4);
model . add ( c ) ;
} // END populatebyrow
The optimal integer solution is (5,0), and the linear programming solution is (1.948, 4.922). The
source code for this example is available in a sample project located at g:/kianfar/isen668/
Tutorial. The file is named as ipex1.cpp. More examples and their source files are available in
folder /examples/src/cpp. Like, ilomipex1.cpp for a basic MIP, and ilolpex1.cpp
for a basic LP.
Note: Copy all the source code files in the sample project to .
Do not store your files in the CPLEX directory, store them on your h: drive.
Do not delete or modify any CPLEX files, especially their licence and source files.
6. Compiling an example to test installation
After you perform all the steps mentioned in Section 4, add your source file corresponding to any
one of the simple examples mentioned in Section 5 to the project. From the Project menu, choose
Add Existing Item. Move to the folder and select any .cpp file, say ilomipex1.cpp.
Click Open. Finally, to build the project, from the Build menu, select Build Solution.
In case of problems, CPLEX offers trouble-shooting procedures. If you encounter difficulty
when you try the installation test, then there is a problem in your installation, and you need to
correct it before you begin real work with CPLEX. For example:
• If you get a message from the compiler such as ilolpex3.cpp 1: Can’t find include
file ilcplex/ilocplex.h then you need to verify that your compiler knows where you
have installed CPLEX and its include files (that is, its header files).
• If you get a message from the linker, such as ld: -lcplex: No such file or directory
then you need to verify that your linker knows where the CPLEX library is located on your
system.
If you successfully compile, link, and execute one of the example, then you can be sure that
your installation is correct, and you can begin to use CPLEX with Concert Technology seriously.
7. Basic Programming Tips
1. Include the headerfile: #include
2. Before the class definition use the macro, ILOSTLBEGIN.
3. Basic Program Structure
9
I loEnv env ; // the environment o b j e c t
try {
env = IloEnv ( ) ; // c r ea t i n g the environment
I loModel model = IloModel ( env ) ; // c r ea t i n g the model (w/env )
// b u i l d some v a r i a b l e s and con s t r a i n t s and add them to the model
model . add ( . . . ) ;
model . add ( I loMin imize ( . . . ) ) ; // add the o b j e c t i v e f unc t i on
I l oCplex cp lex = I loCplex (model ) ; // c rea t e cp l e x o b j e c t w/model
cp lex . s o l v e ( ) ; // s o l v e the model
}
catch ( I l oExcept i on& e ) { . . . }
catch ( . . . ) { . . . }
env . end ( ) ;
4. 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.
5. Data-Types
(a) Constants: IloNum, IloBool, IloInt
(b) Variables: IloNumVar, IloBoolVar, IloIntVar
(c) Arrays: IloIntVarArray, IloNumVarArray, IloBoolVarArray
6. Variables: Objects of class, IloNumVar, represent decision variables in a model. They
are defined by the lower and upper bound for the variable, and a type which can be one of
ILOFLOAT, ILOINT, or ILOBOOL for continuous, integer, or Boolean variables, respectively.
The following constructor creates an integer variable with bounds -4 and 20:
IloNumVar var(env, -4, 20, ILOINT);
The class IloNumVar provides methods that allow querying of the data needed to specify a
variable. However, only bounds can be modified. Concert Technology provides a modeling
object class IloConversion to change the type of a variable. This conversion allows you to
use the same variable with different types in different models.
7. Expressions: Variables are usually used to build up expressions, which in turn are used
to define the objective or constraints of the optimization problem. An expression can be
explicitly written, as in
50 * x[0] - x[1]
where x is assumed to be an array of variables IloNumVarArray. Expressions can also be
created piece by piece, with a loop:
IloExpr expr(env);
for (int i = 0; i < x.getSize(); ++i)
expr += data[i] * x[i];
8. Objective Function: Objects of class IloObjective represent objective functions in opti-
mization models. An objective function is specified by creating an instance of IloObjective.
For example:
10
IloObjective obj(env, - x[1] + 2 * x[2] + 3 * x[3], IloObjective::Minimize);
defines the objective to minimize the expression −x1 + 2x2 + 3x3.
9. Adding Constraint: Similarly, objects of the class IloConstraint represents constraints in
a model. Most constraints also belong to the subclass IloRange, derived from IloConstraint,
and thus inherit its constructors and methods. IloRange represent constraints of the form
lower bound <= expression <= upper bound. In other words, an instance of IloRange is
a convenient way to express a ranged constraint, that is, a constraint with explicit upper or
lower bounds. Any floating-point value or +IloInfinity or -IloInfinity can be used for
the bounds. For example:
IloRange con(env, -IloInfinity, x[0] + x[1], 250);
defines the constraint x0 + x1 <= 250.
10. Formulating a Problem: To formulate a full optimization problem, first create the objects
that are part of it and add them to an instance of IloModel, the class that represents
optimization problems. For example, these lines:
IloModel model(env);
model.add(obj);
model.add(con);
define a model consisting of the objective obj , constraint r1 , and all the variables they use.
For convenience, Concert Technology provides the functions IloMinimize and IloMaximize
to define minimization and maximization objective functions. Also, operators <=, ==, and >=
are overloaded to create IloRange constraints. These features allow to rewrite that example
in a compact and readable way, like this:
IloModel model(env);
model.add(IloMinimize(env, - x[1] + 2*x[2] + 3*x[3]);
model.add(x[0] + x[1] <= 250);
With this notation, you need not create the C++ variables obj and con explicitly (as orig-
inally in the example). There are three following technique to fill the model object with a
representation of the optimization problem (for details refer ilolpex2.cpp):
• populate by row,
• populate by column,
• populate by nonzero.
These functions place the variable and range objects in the arrays, for example var and con
in Section 5, which are passed to them as arguments.
11. Model extraction: After the model has been populated, the IloCplex algorithm object
cplex is created and the model is extracted to it. For example:
IloCplex cplex(model);
11
12. Solving the model: After the model is extracted to the cplex object, solve(); is called
to solve the problem. For most problems this is all that is needed for solving the model.
Nonetheless, CPLEX offers a variety of controls that allow users to tailor the solution process
for their specific needs (for details refer Section 10).
Remark: It is important to note that the examples considered in Sections 5 and 7 are
used only to give basic idea about CPLEX. In this course, an optimization problem
will be modelled and solved as explained in the following example.
8. Example: Multiperiod Production Model
Various examples are delivered with CPLEX in /examples/src. In this section, we
solve a multi-period production model known as steelT.mod in the AMPL book by Fourer, Gay,
and Kernighan (see Section 4.2 in http://www.ampl.com/BOOK/CHAPTERS/07-tut4.pdf). In this
example we would like to find out the optimal level of production, inventory, and sales of each
product in each period subject to the production time limits such that the total revenue minus the
production and inventory cost is minimized. The model and data are as follows:
MODEL : The parameters for the model are:
nProd the number of products
nTime the number of time periods
ratep rate of production for product p
inv0p initial inventory for product p
availt hours available in time period t
marketpt demand for product p in time periodt
prodcostp production cost per unit of product p
invcostp inventory cost per unit of product p
revenuept revenue per unit of product p in time period t
The decision variables of the model are:
Makept amount produced of product p in time period t
Invpt amount inventoried of product p in time period t
Sellpt amount sold of product p in time period t
The objective function is to maximize
nProd∑
p=1
nTime∑
t=1
{
(revenuept × Sellpt)− (prodcostp ×Makept)− (invcostp × Invpt)
}
The constraints are:
1. Time availability constraints
nProd∑
p=1
(1/ratep)×Makept ≤ availp, 1 ≤ t ≤ nTime
12
2. Material balance constraints
Makept + Invp,t−1 − Sellpt − Invpt = 0 1 ≤ p ≤ nProd, 1 ≤ t ≤ nTime
Makep0 − Sellp0 − Invp0 = −inv0p 1 ≤ p ≤ nProd
3. The bounds on the variables are:
Sellpt <= marketpt 1 ≤ p ≤ nProd, 1 ≤ t ≤ nTime
Makept, Invpt, Sellpt ≥ 0 1 ≤ p ≤ nProd, 1 ≤ t ≤ nTime
DATA: We will use the following values for parameters of the model:
Number of time periods = 4
Hours available in period 1 = 40
Hours available in period 2 = 40
Hours available in period 3 = 32
Hours available in period 4 = 40
Number of products = 2 (say bands and coils)
Rate of bands = 200
Rate of coils = 140
Initial inventory of bands = 10
Initial inventory of coils = 0
Production cost per unit of bands = 10
Production cost per unit of coils = 11
Inventory cost per unit of bands = 2.5
Inventory cost per unit of coild = 3
revenue: 1 2 3 4 (periods)
bands 25 26 27 27
coils 30 35 37 39
market: 1 2 3 4 (periods)
bands 6000 6000 4000 6500
coils 4000 2500 3500 4200
Next, we present C++ code to solve the multi-period production model using CPLEX Concert
Technology. This code is also available in g:/kianfar/isen668/Tutorial.
#include < i l c p l e x / i l o c p l e x . h>
ILOSTLBEGIN
typedef I loArray IloNumVarArray2 ;
int main ( int argc , char ∗∗ argv ){
I loEnv env ;
try {
const char∗ f i l ename = ” s t e e l . dat” ;
/∗ The data f i l e con ta ins :
13
[ 0 , 40 , 40 , 32 , 40]
[200 , 140]
[10 , 0 ]
[10 , 11]
[ 2 . 5 , 3 ]
[ [ 0 , 25 , 26 , 27 , 27 ] , [ 0 , 30 , 35 , 37 , 3 9 ] ]
[ [ 0 , 6000 , 6000 , 4000 , 6500] , [ 0 , 4000 , 2500 , 3500 , 4200 ] ] ∗/
i f ( argc >= 2) f i l ename = argv [ 1 ] ;
i f s t r e am f i l e ( f i l ename ) ;
i f ( ! f i l e ) {
c e r r << ”No such f i l e : ” << f i l ename << endl ;
throw(−1);
}
IloNumArray av a i l ( env ) , r a t e ( env ) , inv0 ( env ) , prodCost ( env ) , invCost ( env ) ;
IloNumArray2 revenue ( env ) , market ( env ) ;
f i l e >> av a i l >> r a t e >> inv0 >> prodCost >> invCost >> revenue >> market ;
I l o I n t nProd = ra t e . g e tS i z e ( ) ;
I l o I n t nTime = ava i l . g e tS i z e ( ) ;
I l o I n t p , t ;
I loModel mod( env ) ;
// VARIABLES
IloNumVarArray2 Make( env ) ;
for (p = 0 ; p < nProd ; p++) {
Make . add ( IloNumVarArray ( env , nTime , 0 . 0 , I l o I n f i n i t y ) ) ;
}
IloNumVarArray2 Inv ( env ) ;
for (p = 0 ; p < nProd ; p++) {
Inv . add ( IloNumVarArray ( env , nTime , 0 . 0 , I l o I n f i n i t y ) ) ;
}
IloNumVarArray2 S e l l ( env ) ;
for (p = 0 ; p < nProd ; p++) {
S e l l . add ( IloNumVarArray ( env , 0 . 0 , market [ p ] ) ) ;
}
/∗ OBJECTIVE i s to maximize t o t a l p r o f i t
sum( over p , t ) ( revenue [ p ] [ t ] ∗ S e l l [ p ] [ t ]
− prodcos t [ p ] ∗ Make [ p ] [ t ]
− i n v c o s t [ p ] ∗ Inv [ p ] [ t ] ) ∗/
I loExpr TotalRevenue ( env ) , TotalProdCost ( env ) , TotalInvCost ( env ) ;
for (p = 0 ; p < nProd ; p++) {
for ( t = 1 ; t < nTime ; t++) {
TotalRevenue += revenue [ p ] [ t ] ∗ S e l l [ p ] [ t ] ;
TotalProdCost += prodCost [ p ] ∗ Make [ p ] [ t ] ;
TotalInvCost += invCost [ p ] ∗ Inv [ p ] [ t ] ;
}
}
mod . add ( IloMaximize ( env , TotalRevenue − TotalProdCost − TotalInvCost ) ) ;
TotalRevenue . end ( ) ;
TotalProdCost . end ( ) ;
TotalInvCost . end ( ) ;
14
/∗ TIME AVAILABILITY CONSTRAINTS
For each t : sum( over p ) ((1/ ra t e [ p ] ) ∗ Make [ p ] [ t ] ) <= av a i l [ t ] ∗/
for ( t = 0 ; t < nTime ; t++) {
I loExpr avai lExpr ( env ) ;
for (p = 0 ; p < nProd ; p++) {
avai lExpr += (1/ ra t e [ p ] ) ∗ Make [ p ] [ t ] ;
}
mod . add ( avai lExpr <= ava i l [ t ] ) ;
ava i lExpr . end ( ) ;
}
/∗ MATERIAL BALANCE CONSTRAINTS
( i ) For each p , ( t =0): Make [ p ] [ 0 ] − S e l l [ p ] [ 0 ] − Inv [ p ] [ 0 ] = −inv0 [ p ]
( i i ) For each pa i r (p , t ) ( t >0):
Make [ p ] [ t ] + Inv [ p ] [ t−1] − S e l l [ p ] [ t ] − Inv [ p ] [ t ] = 0 ∗/
for (p = 0 ; p < nProd ; p++) {
mod . add (Make [ p ] [ 0 ] + inv0 [ p ] == S e l l [ p ] [ 0 ] + Inv [ p ] [ 0 ] ) ;
for ( t = 1 ; t < nTime ; t++) {
mod . add (Make [ p ] [ t ] + Inv [ p ] [ t−1] == S e l l [ p ] [ t ] + Inv [ p ] [ t ] ) ;
}
}
I l oCplex cp lex (mod ) ;
cp l ex . exportModel ( ” s t e e l . lp ” ) ;
cp l ex . s o l v e ( ) ;
env . out ( ) << endl << ”Total P r o f i t = ” << cp lex . getObjValue ( ) << endl ;
env . out ( ) << endl << ”\ tp\ t t \tMake\ t Inv \ t S e l l ” << endl ;
for (p = 0 ; p < nProd ; p++) {
for ( t = 0 ; t < nTime ; t++) {
env . out ( ) << ’ \ t ’ << p
<< ’ \ t ’ << t
<< ’ \ t ’ << cp lex . getValue (Make [ p ] [ t ] )
<< ’ \ t ’ << cp lex . getValue ( Inv [ p ] [ t ] )
<< ’ \ t ’ << cp lex . getValue ( S e l l [ p ] [ t ] ) << endl ;
}
}
}
catch ( I l oExcept i on& ex ) {
c e r r << ”Error : ” << ex << endl ;
}
catch ( . . . ) {
c e r r << ”Error : Unknown except ion caught ! ” << endl ;
}
env . end ( ) ;
return 0 ;
}
15
9. Advanced Programming Tips [1]
9.1 Accessing solution information
If a solution is found, solution information is output through the channel, env.out which is ini-
tialized to cout by default. The output operator << is defined for type IloAlgorithm::Status as
returned by the call to getStatus. It is also defined for IloNumArray, the Concert Technology class
for an array of numerical values, as returned by the calls to getValues, getDuals, getSlacks, and
getReducedCosts. In general, the output operator is defined for any Concert Technology array of
elements if the output operator is defined for the elements. If a solution has been found with the
solve method, you access it and then query it using following IloCplex methods.
(a) getObjValue:
The objective function can be accessed by the call: double objval = cplex.getObjValue();
(b) getValue:
The values of individual modeling variables for the solution are accessed by the methods
IloCplex.getValue, for example:
double x1 = cplex.getValue(var1); or double[] x = cplex.getValues(vars);
(c) getSlack:
Similar to getValue method, you can query slack values for the constraints in the active model
by means of the methods IloCplex.getSlack or IloCplex.getSlacks.
(d) getNiterations:
This method returns the number of iterations that occurred during the last call to the method
IloCplex::solve in the invoking algorithm.
(e) getNnodes:
This method returns the number of branch-and-cut nodes that were processed in the current
solution. If the invoking IloCplex object is not a MIP, it returns 0.
(f) getNcuts:
This method returns the number of cuts of the specified type in use at the end of the previous
mixed integer optimization. If the invoking IloCplex object is not a MIP, it returns 0.
(g) getBestObjValue:
This method returns a bound on the optimal solution value of the problem. When a model has
been solved to optimality, this value matches the optimal solution value. If a MIP optimization
is terminated before optimality has been proven, this value is computed for a minimization
(maximization) problem as the minimum (maximum) objective function value of all remaining
unexplored nodes.
(h) getCplexStatus:
This method returns the ILOG CPLEX status of the invoking algorithm. For possible ILOG
CPLEX values, see the enumeration type IloCplex::CplexStatus.
(i) getParameterSet:
This method returns a parameter set corresponding to the present parameter state. If the
method fails, an exception of type IloException, or one of its derived classes, is thrown.
16
9.2 Import data from .mps, .lp, or .sav file
The samples ilomipex2.cpp and ilolpex2.cpp (available in folder ) illustrate reading a model
from a file with .mps, .lp, or .sav extension. It is important to note that in both samples the
method importModel of an IloCplex object reads the model from the file but it does not extract
the model for solution. That is, in this case, the IloCplex object is used as a model reader rather
than an optimizer. Calling importModel does not extract the model to the invoking cplex object.
Consequently, extraction must be done later by a call to cplex.extract(model).
9.3 Modifying an optimization problem
A look back to examples ilolpex1.cpp and ilolpex2.cpp reveals that models have been modified
all along. Each time an extractable object is added to a model, it changes the model. However,
those examples made all such changes before the model was extracted to CPLEX. The sample
ilolpex3.cpp shows how to modify a model so that CPLEX can re-optimize and re-use any
information available from previous optimizations. The example ilolpex3.cpp is based on a
network flow model. The idea is to solve the simple problem first, and then add the constraints for
the complicating constraints, and solve with dual.
9.4 Output messages
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.
9.5 Debugging (handling error)
We now describe error handling in the C++ API. The errors in Concert Technology are classified
under two categories:
I. Programming errors, such as:
• accessing empty handle objects;
• mixing modeling objects from different environments;
• accessing Concert Technology array elements beyond an array’s size; and
• passing arrays of incompatible size to functions.
Such errors are usually an oversight of the programmer. After they are recognized and fixed
there is usually no danger of corrupting an application. In a production application, it is not
necessary to handle these kinds of errors. In Concert Technology such error conditions are
handled using assert statements.
II. Runtime errors, such as memory exhaustion. A correct program assumes that such failures can
occur and therefore must be treated, even in a production application. In Concert Technology,
if such an error condition occurs, an exception is thrown.
17
10. Setting CPLEX parameters
The behavior of CPLEX is controlled by a variety of parameters that are each accessible and
settable by the user. This section lists some of these parameters and explains their settings in the
CPLEX Concert Technology with C++. In C++ programs using Concert, the parameter name is
preceded by "IloCplex::". It is not generally necessary to distinguish among integer, Boolean,
numeric, and string parameters. Example usage:
cplex.setParam(IloCplex::AdvInd, 0);
IloCplex provides a variety of parameters that allow to control the solution process. In the
following parameter table, each parameter has a name (that is, a symbolic constant) to refer to it
within an application. For example, IloCplex::TiLim is the IloCplex parameter available in the
C++ to set a limit on the elapsed time in solving a MIP.
Classification Parameter Purpose
TiLim To set a limit on elapsed time
Parameters to NodeLim MIP node limit
limit MIP TreLim Limits tree memory
optimization IntSolLim Limits number of integer solutions
EpGap Limits relative MIP gap tolerance
EpAGap Limits absolute MIP gap tolerance
AggInd Preprocessing aggregator application limit
PreInd Presolve switch
Parameters for BndStrenInd Bound strengthening switch
controlling MIP CoeRedInd Coefficient reduction setting
preprocessing RelaxPreInd Relaxed LP presolve switch
Reduce Primal and dual reduction type
PrePass Limit on the number of presolve passes made
RepeatPresolve MIP repeat presilve switch
Cliques MIP cliques switch
Covers MIP covers switch
DisjCuts MIP disjuctive cuts switch
Parameters for FlowCovers MIP flow cover cuts switch
controlling cuts FlowPaths MIP flow path cut switch
FracCuts MIP Gomory fractional cuts switch
GUBCovers MIP GUB cuts switch
ImplBd MIP implied bound cuts switch
MIRCuts MIP MIR(mixed integer rounding) cut switch
setParam(BtTol,n) Backtracking tolerance
Parameters for setParam(NodeSel,i) MIP node selectin strategy
controlling branch- setParam(VarSel,i) MIP variable selection strategy
and-cut strategy setParam(BBInterval,i) MIP strategy best bound interval
setParam(BrDir,i) MIP branching direction
For details of each of these parameters along with remaining other parameters, consult ILOG
CPLEX Reference Manual [1].
18
References
[1] IBM ILOG CPLEX Optimization Studio V12.2 Documentation,
http://pic.dhe.ibm.com/infocenter/cosinfoc/v12r2/
[2] http://www-03.ibm.com/ibm/university/academic/pub/page/mem_join
[3] http://www-03.ibm.com/ibm/university/academic/pub/page/ban_ilog_programming
19
CHEAT SHEET: ILOG CPLEX C++ Classes
Step 1. Create Environment
IloEnv env;
Step 2. Define Parameters
• IloNum: Continuous number
• IloInt: Integral constant
• IloBool: Boolean constant
• IloNumArray: Array of continuous numbers
• IloIntArray: Array of integers
• IloBoolArray: Array of booleans
• IloArray: Matrix (2D array) of continuous numbers
Step 3. Initialize Variables
• IloNumVar: Continuous variable
• IloIntVar: Integral variable
• IloBoolVar: Boolean variable
• IloNumVarArray: Array of continuous variables
• IloIntVarArray: Array of integer variables
• IloBoolVarArray: Array of boolean variables
• IloArray: Matrix (2D array) of integer variables
Step 4. Initialize Model
IloModel model(env);
Step 5. Build Objective Funtion Expression
IloExpr exprObj(env);
for (int i = 0; i < arrayofvar.getSize(); ++i)
exprObj += data0[i] * arrayofvar[i];
Step 6. Add Objective Funtion to Model
model.add(IloMinimize(env, exprObj));
Step 7. Build Constraint Expression
IloExpr exprCon(env);
for (int i = 0; i < arrayofvar.getSize(); ++i)
exprCon += arrayofparameter[i] * arrayofvar[i];
Step 8. Add Constraint to Model
model.add(exprCon <= datavalue);
Step 9. Extract and Solve Model
IloCplex cplex(model); cplex.solve();