Posts

Installing Cplex in Linux Ubuntu

I’ve been trying to install ILOG’s Cplex product on a 64 bit Ubuntu machine. There are a few small hiccups I encountered.

First, try to install as root with

./cplex_studio122.linux-x86.bin

On my machine I’m installing to /opt/ILOG/CPLEX_Studio122. If you get an error like “jre/bin/java: not found” then you need the “32 bit libs” package:

apt-get install ia32-libs

(You may also need to set the path with LD_LIBRARY_PATH=/usr/lib32). The 32 bit libraries seem to be required only for the installer (at least, they are not needed for programs that just link with the static Cplex libs).

After installing, you may get a build error (running as a non-root user) that it can’t find the cplex header files. Try ls /opt/ILOG/CPLEX_Studio122 and see if there are permission denied messages – the installation seems to screw up some permissions on this folder, however this is easily fixed with chmod +r /opt/ILOG/CPLEX_Studio122.

If you are using COIN-OR‘s Osi class OsiCpxSolverInterface you will also need the following at the top of your OsiCpxSolverInterface.cpp file:

#include “/opt/ILOG/CPLEX_Studio122/cplex/include/ilcplex/cplex.h”

A typical Makefile snippet which includes Cplex and COIN/Osi might then look like:

my_objects = YourFile.o OsiCbcSolverInterface.o OsiCpxSolverInterface.o

CPPFLAGS = -fPIC -I/usr/include -I/usr/include/coin -DNDEBUG -I/opt/ILOG/CPLEX_Studio122/cplex/include/ilcplex

LIBFLAGS = -l:libCbc.so -l:libCbcSolver.so -l:libCoinUtils.so -l:libOsi.so -l:libOsiClp.so -l:libClp.so -l:/opt/ILOG/CPLEX_Studio122/cplex/lib/x86-64_sles10_4.1/static_pic/libcplex.a -l:/opt/ILOG/CPLEX_Studio122/cplex/lib/x86-64_sles10_4.1/static_pic/libilocplex.a

my_program : $(my_objects)
g++ -Wall -fPIC -shared -o my_program $(my_objects)

.PHONY : clean

clean :
rm *.o my_program

Re-solving Linear Programs with COIN-OR

I recently had to go from solving a Linear Program (LP) once only, to modifying the problem and re-solving it multiple times. I was using the excellent open source COIN-OR libraries as my interface (OSI) and solver (CLP).

I found that you will get obscure-looking crashes (though, to be sure, I am using the downloaded binaries, not building COIN from source) inside OSI/COIN if you do not keep around the matrix and vector objects that you use to build your LP. It is safe to delete these objects if you are solving the problem once only, even before you have called initialSolve(). But it is not safe if you have to re-solve the LP!

A simple generic little helper class I used for this is:

class LPObjects
{
public:
CoinPackedMatrix* m_matrix;
double* m_objective, * m_col_lb, * m_col_ub, * m_rowrhs, * m_rowsen;

LPObjects()
{
m_objective = NULL;
m_col_lb = m_col_ub = NULL;
m_rowrhs = m_rowsen = NULL;
m_matrix = NULL;
}

void Create(int n_cols, int n_rows, double dblInfinity)
{
m_objective = new double[n_cols]; //the objective coefficients
m_col_lb = new double[n_cols]; //the column lower bounds
m_col_ub = new double[n_cols]; //the column upper bounds
m_rowrhs = new double[n_rows]; //the row rhs
m_rowsen = new char[n_rows]; //the row sense

for (int i = 0; i
m_objective[i] = 0.0;
for (int i = 0; i
{
m_col_lb[i] = 0.0;
m_col_ub[i] = dblInfinity;
}
m_matrix = new CoinPackedMatrix(false, 0, 0);
m_matrix->setDimensions(0, n_cols);
}
};

If si is your OsiXxxSolverInterface object, and g_LP is a static pointer to an instance of LPObjects, then g_LP can be initialised with:

if (g_LP == NULL)
{
g_LP = new LPObjects;
g_LP->Create(n_cols, n_rows, si->getInfinity());
}

Create your problem representation by filling out rowrhs, rowsen, etc, and be sure to use CoinPackedMatrix’s appendRows to populate your matrix coefficients in bulk rather than using multiple calls to appendRow (which is much much slower for larger LPs).

Then load your problem into OSI with:

si->loadProblem(*g_LP->m_matrix, g_LP->m_col_lb, g_LP->m_col_ub, g_LP->m_objective, g_LP->m_rowsen, g_LP->m_rowrhs, NULL);

and solve with si->initialSolve(). Now you change the LP using the usual methods such as si->setColUpper(), and re-solve with si->resolve(). Note your call to si->setColUpper() (or whatever) does not directly reference the matrix or vectors of g_LP, but those objects must remain in memory!

Code used with binary distribution “CoinAll-1.2.0-win32-msvc9” under Windows Vista / Visual C++ Express 2008.