You are on page 1of 20

CPLEX Concert Technology using C++

A Tutorial

Prepared by:
Manish Bansal
Kiavash Kianfar

April 2013

Version 1.0

Contents
1 CPLEX Concert Technology: An Introduction

2 Access to CPLEX

3 Setting up CPLEX Concert with C++ on Windows in Release Mode

4 Setting up CPLEX Concert with C++ on Windows in Debug Mode

5 Solving an IP with CPLEX Concert Technology using C++

6 Compiling an example to test installation

7 Basic Programming Tips

8 Example: Multiperiod Production Model


9 Advanced Programming Tips [1]
9.1 Accessing solution information . . . . . .
9.2 Import data from .mps, .lp, or .sav file
9.3 Modifying an optimization problem . . . .
9.4 Output messages . . . . . . . . . . . . . .
9.5 Debugging (handling error) . . . . . . . .

14

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

17
17
19
19
19
19

10 Setting CPLEX parameters

20

References

20

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 interactively 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 supporting 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 dont 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 softwares, 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 IBMs Academic Initiative program, which provides no-charge access to full-version software 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, register 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.

Remark: Throughout this document, the Concert Technology installation folder is referred
to as <CONCERTDIR>, and the CPLEX installation folder is referred to as <CPLEXDIR>. If you
are accessing CPLEX from ISEN lab then <CONCERTDIR> represents J:\CPLEX12x64\ILOG\
Concert29, and <CPLEXDIR> represents J:\CPLEX12x64\ILOG\CPLEX121. While if you have
installed the CPLEX in folder, say for example, C:\ILOG\CPLEX, references to <CONCERTDIR>\
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 <CPLEXDIR>. 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, <ProjName>.
(g) If necessary, correct the location of the project (to <MYPROJDIR>)
(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:
<CPLEXDIR>\include, <CONCERTDIR>\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
<CPLEXDIR>\lib\x64_windows_vs2008\stat_mta\cplex121.lib
<CPLEXDIR>\lib\x64_windows_vs2008\stat_mta\ilocplex.lib
<CONCERTDIR>\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 <CPLEXDIR>\bin\x64_win64 and copy the file cplex121.dll to folder
<MYPROJDIR>\<ProjName>\<ProjName>, 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: <CPLEXDIR>\bin\x64_win64
(f) Restart Visual Studio for this change in the operating system to take effect.

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, <ProjName>.
(g) If necessary, correct the location of the project (to <MYPROJDIR>)
(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:
<CPLEXDIR>\include, <CONCERTDIR>\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 Preprocessor 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
<CPLEXDIR>\lib\x64_windows_vs2008\stat_mta\cplex121.lib
<CPLEXDIR>\lib\x64_windows_vs2008\stat_mta\ilocplex.lib
<CONCERTDIR>\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 <CPLEXDIR>\bin\x64_win64 and copy the file cplex121.dll to folder
<MYPROJDIR>\<ProjName>\<ProjName>, 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: <CPLEXDIR>\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
s t a t i c void
populatebyrow ( I l o M o d e l model , IloNumVarArray var , Il oRang eArra y con ) ;
i n t main ( void ) {
I l o E n v env ;
try {
I l o M o d e l model ( env ) ;
IloNumVarArray var ( env ) ;
I l o R ange Array con ( env ) ;
populatebyrow ( model , var , con ) ;
I l o C p l e x c p l e x ( model ) ;
cplex . solve ( ) ;
env . out ( ) << S o l u t i o n s t a t u s = << c p l e x . g e t S t a t u s ( ) << e n d l ;
env . out ( ) << S o l u t i o n v a l u e = << c p l e x . getObjValue ( ) << e n d l ;
IloNumArray v a l s ( env ) ;
c p l e x . g e t V a l u e s ( v a l s , var ) ;
env . out ( ) << Values
= << v a l s << e n d l ;
c p l e x . g e t S l a c k s ( v a l s , con ) ;
env . out ( ) << S l a c k s
= << v a l s << e n d l ;

c p l e x . exportModel ( i p e x 1 . l p ) ;
}
catch ( I l o E x c e p t i o n& e ) {
c e r r << Concert e x c e p t i o n caught : << e << e n d l ;
}
catch ( . . . ) {
c e r r << Unknown e x c e p t i o n caught << e n d l ;
}
env . end ( ) ;
return 0 ;
// END main

s t a t i c void
populatebyrow ( I l o M o d e l model , IloNumVarArray x , I loRan geArr ay c ) {
I l o E n v env = model . getEnv ( ) ;

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 l o M a x i m i z e ( env , 1 . 0 0 x [ 0 ] + 0 . 6 4 x [ 1 ] ) ) ;
c . add ( 50 x [ 0 ] + 31 x [ 1 ] <= 2 5 0 ) ;
c . add ( 3 x [ 0 ] 2 x [ 1 ] >= 4);
model . add ( c ) ;
}

// END p o p u l a t e b y r o w

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 <CPLEXDIR>/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 <MYAPPDIR>.
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 <MYAPPDIR> 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: Cant 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<ilcplex/ilocplex.h>
2. Before the class definition use the macro, ILOSTLBEGIN.
3. Basic Program Structure

I l o E n v env ; // t h e environment o b j e c t
try {
env = I l o E n v ( ) ; // c r e a t i n g t h e environment
I l o M o d e l model = I l o M o d e l ( env ) ; // c r e a t i n g t h e model (w/ env )
// b u i l d some v a r i a b l e s and c o n s t r a i n t s and add them t o t h e model
model . add ( . . . ) ;
model . add ( I l o M i n i m i z e ( . . . ) ) ; // add t h e o b j e c t i v e f u n c t i o n
I l o C p l e x c p l e x = I l o C p l e x ( model ) ; // c r e a t e c p l e x o b j e c t w/ model
c p l e x . s o l v e ( ) ; // s o l v e t h e model
}
catch ( I l o E x c e p t i o n& 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 optimization 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 originally 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 <CONCERTDIR>/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:
nP rod

the number of products

nT ime

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:


M akept

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


nP
rod nT
ime 
X
X
p=1


(revenuept Sellpt ) (prodcostp M akept ) (invcostp Invpt )

t=1

The constraints are:


1. Time availability constraints
nP
rod
X

(1/ratep ) M akept availp , 1 t nT ime

p=1

12

2. Material balance constraints


M akept + Invp,t1 Sellpt Invpt = 0

1 p nP rod, 1 t nT ime

M akep0 Sellp0 Invp0 = inv0p

1 p nP rod

3. The bounds on the variables are:


Sellpt <= marketpt

1 p nP rod, 1 t nT ime

M akept , Invpt , Sellpt 0

1 p nP rod, 1 t nT ime

DATA: We will use the following values for parameters of the model:
Number of time periods = 4
Hours available in period 1 =
Hours available in period 2 =
Hours available in period 3 =
Hours available in period 4 =

40
40
32
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:
bands
coils

1
25
30

2
26
35

3
27
37

4
27
39

(periods)

market:
bands
coils

1
6000
4000

2
6000
2500

3
4000
3500

4
6500
4200

(periods)

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 l o A r r a y <IloNumVarArray>

IloNumVarArray2 ;

i n t main ( i n t argc , char argv ) {


I l o E n v env ;
try {
const char f i l e n a m e = s t e e l . dat ;
/ The d a t a f i l e c o n t a i n s :

13

[ 0 , 40 , 40 , 32 , 4 0 ]
[200 , 140]
[10 , 0]
[10 , 11]
[2.5 , 3]
[ [ 0 , 25 , 26 , 27 , 2 7 ] , [ 0 , 30 , 35 , 37 , 3 9 ] ]
[ [ 0 , 6000 , 6000 , 4000 , 6 5 0 0 ] , [ 0 , 4000 , 2500 , 3500 , 4 2 0 0 ] ]

i f ( a r g c >= 2 ) f i l e n a m e = argv [ 1 ] ;
ifstream f i l e ( filename ) ;
if ( ! file ) {
c e r r << No such f i l e : << f i l e n a m e << e n d l ;
throw ( 1);
}
IloNumArray a v a i l ( env ) , r a t e ( env ) , i n v 0 ( env ) , prodCost ( env ) , i n v C o s t ( env ) ;
IloNumArray2 r e v e n u e ( env ) , market ( env ) ;
f i l e >> a v a i l >> r a t e >> i n v 0 >> prodCost >> i n v C o s t >> r e v e n u e >> market ;
I l o I n t nProd = r a t e . g e t S i z e ( ) ;
I l o I n t nTime = a v a i l . g e t S i z e ( ) ;
IloInt p, t ;
I l o M o d e l mod( env ) ;
// VARIABLES
IloNumVarArray2 Make ( env ) ;
f o r ( 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 ) ;
f o r ( 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 ) ;
f o r ( p = 0 ; p < nProd ; p++) {
S e l l . add ( IloNumVarArray ( env , 0 . 0 , market [ p ] ) ) ;
}
/ OBJECTIVE i s t o maximize t o t a l p r o f i t
sum ( o v e r p , t ) ( r e v e n u e [ p ] [ t ] S e l l [ p ] [ t ]
prodcost [ p ]
Make [ p ] [ t ]
invcost [ p ]
I n v [ p ] [ t ] ) /
I l o E x p r TotalRevenue ( env ) , TotalProdCost ( env ) , T o t a l I n v C o s t ( env ) ;
f o r ( p = 0 ; p < nProd ; p++) {
f o r ( t = 1 ; t < nTime ; t++) {
TotalRevenue += r e v e n u e [ p ] [ t ] S e l l [ p ] [ t ] ;
TotalProdCost += prodCost [ p ] Make [ p ] [ t ] ;
T o t a l I n v C o s t += i n v C o s t [ p ] Inv [ p ] [ t ] ;
}
}
mod . add ( I l o M a x i m i z e ( env , TotalRevenue TotalProdCost T o t a l I n v C o s t ) ) ;
TotalRevenue . end ( ) ;
TotalProdCost . end ( ) ;
T o t a l I n v C o s t . end ( ) ;

14

/ TIME AVAILABILITY CONSTRAINTS


For each t : sum ( o v e r p ) ( ( 1 / r a t e [ p ] ) Make [ p ] [ t ] ) <= a v a i l [ t ] /
f o r ( t = 0 ; t < nTime ; t++) {
I l o E x p r a v a i l E x p r ( env ) ;
f o r ( p = 0 ; p < nProd ; p++) {
a v a i l E x p r += ( 1 / r a t e [ p ] ) Make [ p ] [ t ] ;
}
mod . add ( a v a i l E x p r <= a v a i l [ t ] ) ;
a v a i l E x p r . end ( ) ;
}
/ MATERIAL BALANCE CONSTRAINTS
( i ) For each p , ( t =0): Make [ p ] [ 0 ] S e l l [ p ] [ 0 ] I n v [ p ] [ 0 ] = i n v 0 [ p ]
( i i ) For each p a i r ( p , t ) ( t >0):
Make [ p ] [ t ] + I n v [ p ] [ t 1] S e l l [ p ] [ t ] I n v [ p ] [ t ] = 0 /

f o r ( p = 0 ; p < nProd ; p++) {


mod . add ( Make [ p ] [ 0 ] + i n v 0 [ p ] == S e l l [ p ] [ 0 ] + Inv [ p ] [ 0 ] ) ;
f o r ( 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 o C p l e x c p l e x (mod ) ;
c p l e x . exportModel ( s t e e l . l p ) ;
cplex . solve ( ) ;
env . out ( ) << e n d l << T o t a l P r o f i t = << c p l e x . getObjValue ( ) << e n d l ;
env . out ( ) << e n d l << \ tp \ t t \tMake\ t I n v \ t S e l l << e n d l ;
f o r ( p = 0 ; p < nProd ; p++) {
f o r ( t = 0 ; t < nTime ; t++) {
env . out ( ) << \ t << p
<< \ t << t
<< \ t << c p l e x . g e t V a l u e ( Make [ p ] [ t ] )
<< \ t << c p l e x . g e t V a l u e ( Inv [ p ] [ t ] )
<< \ t << c p l e x . g e t V a l u e ( S e l l [ p ] [ t ] ) << e n d l ;
}
}
}
catch ( I l o E x c e p t i o n& ex ) {
c e r r << E r r o r : << ex << e n d l ;
}
catch ( . . . ) {
c e r r << E r r o r : Unknown e x c e p t i o n caught ! << e n d l ;
}
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 initialized 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 arrays 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
Parameters to
limit MIP
optimization

Parameters for
controlling MIP
preprocessing

Parameters for
controlling cuts

Parameters for
controlling branchand-cut strategy

Parameter
TiLim
NodeLim
TreLim
IntSolLim
EpGap
EpAGap
AggInd
PreInd
BndStrenInd
CoeRedInd
RelaxPreInd
Reduce
PrePass
RepeatPresolve
Cliques
Covers
DisjCuts
FlowCovers
FlowPaths
FracCuts
GUBCovers
ImplBd
MIRCuts
setParam(BtTol,n)
setParam(NodeSel,i)
setParam(VarSel,i)
setParam(BBInterval,i)
setParam(BrDir,i)

Purpose
To set a limit on elapsed time
MIP node limit
Limits tree memory
Limits number of integer solutions
Limits relative MIP gap tolerance
Limits absolute MIP gap tolerance
Preprocessing aggregator application limit
Presolve switch
Bound strengthening switch
Coefficient reduction setting
Relaxed LP presolve switch
Primal and dual reduction type
Limit on the number of presolve passes made
MIP repeat presilve switch
MIP cliques switch
MIP covers switch
MIP disjuctive cuts switch
MIP flow cover cuts switch
MIP flow path cut switch
MIP Gomory fractional cuts switch
MIP GUB cuts switch
MIP implied bound cuts switch
MIP MIR(mixed integer rounding) cut switch
Backtracking tolerance
MIP node selectin strategy
MIP variable selection strategy
MIP strategy best bound interval
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<IloNumArray>: 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<IloIntVarArray>: 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();

You might also like