GLPK/Mixing GLPK with other solver packages

Users, on occasion, prefer to generate their problems with GLPK, but then solve them with another solver. Or conversely, import problems into GLPK which have been generated by another solver package. This page concentrates on the options involving high-level programming.

Introduction
First, the term foreign solver package refers to products like CPLEX or lp_solve. The motivations for combining two packages are various and not discussed here.

The options for shuffling between GLPK and another solver package can be tackled on three levels:


 * shell scripting to invoke each solver in turn via its command-line, while exchanging data via the filesystem using a common problem format (like MPS)


 * high-level programming using API calls from both GLPK and the foreign package, but still exchanging data via the filesystem


 * high-level programming using API calls from both GLPK and the foreign package, but using in-memory data structures instead

More information on standard problem formats can be found on the interoperability page.

COIN-OR Open solver interface (Osi)
The Osi initiative is described elsewhere in this book.

Compiling the COIN-OR CBC solver with mathprog
Using versions 2.7 or later, COIN-OR CBC solver can compile in the GLPK mathprog language as an input modelling language, although at this time no output features, such as database output or console printf statements, are supported. The COIN-OR CBC solver has implemented multi-threaded operation for the MIP solution techniques and is currently able to solve much larger and more complex MIP problems than GLPK.

Version 2.7 of the COIN-OR CBC solver currently uses GLPK 4.45 although it is planned to use 4.47 for the 2.8 release.

To compile and run the CBC solver on linux or Max OSX platforms follow the following steps (stable release 2.7 using a fresh install of Ubuntu 12.10 64 bit as an example):

~$ sudo apt-get install build-essential ~$ sudo apt-get install autoconf ~$ sudo apt-get install subversion ~$ svn co https://projects.coin-or.org/svn/Cbc/stable/2.7 coin-Cbc ~$ cd coin-Cbc/ThirdParty/Glpk ~/coin-Cbc/ThirdParty/Glpk$ ./get.Glpk ~/coin-Cbc/ThirdParty/Glpk$ ./configure ~/coin-Cbc/ThirdParty/Glpk$ cd ../.. ~/coin-Cbc$ ./configure CFLAGS='-m64 -O3' CC=gcc-4.7 --enable-gnu-packages --enable-cbc-parallel --enable-debug -C --prefix=/usr/local ~/coin-Cbc$ make -j 8 [if you want to use parallel compilation - just 'make' otherwise] ~/coin-Cbc$ sudo make install

Now copy your mathprog model to the machine and run the model, writing all of the computed variables to a csv file:

cbc modelname.mod% -randomCbcSeed 0 -randomSeed 0 -proximity on -threads 8 -printi csv -solve -solu modelname.csv

Note the '%' at the end of the model name indicating that it is a mathprog model.

Filesystem interchange
The simplest high-level method is to use the filesystem to transfer the problem between GLPK and the foreign solver, and then transfer the solution back

For example, GLPK could write out the problem in free MPS format format, call the external solver, and then load the solution back into a new (second) glpk problem object. In this case, the API routines glp_write_prob, glp_read_mip, and glp_write_mip should be useful. In the unlikely event that hard-drive I/O contributes to poor performance, a RAM-drive can be deployed.

In-memory method
If the foreign solver has a suitable API, then the entire exercise can take place in the program space.

The following example uses CPLEX. CPLEX is a leading commercial solver suite, purchased in 2009 by IBM. Here GLPK is used to build a GLPK problem, transform that problem into a CPLEX problem, call CPLEX to solve the problem, and finally recover the solution. The following public domain C code titled 3party.c does just this. Users should be cautioned that 3party.c uses internal (non-public) data structures from GLPK &mdash; although the code could be easily rewritten to use published API data structures. It is always bad practice to stray from the public interface.

CPLEX interoperation
CPLEX is a proprietary optimization software package from IBM. This mid-2011 thread discusses the converting of solutions between CPLEX and GLPK.

MiniSat CNF-SAT solver
From version 4.46, GLPK bundles the MiniSat CNF-SAT or conjunctive normal form satisfiability problem solver developed by Niklas Eén and Niklas Sörensson at the Chalmers University of Technology, Sweden. MiniSat's permissive MIT license allows it to be distributed as part of GLPK. The MiniSat wrapper call is named glp_minisat1.

Version 4.47 introduced the glp_intfeas1 API which offers a native implementation of the MiniSat code &mdash; please be aware that this function was marked "tentative" in this release. The GLPSOL option --minisat now redirects to this new solver.

A satisfiability (SAT) problem involves determining if a given boolean formula can evaluate TRUE through the suitable assignment of its variables. The conjunctive normal form (CNF) indicates restrictions on the way the boolean formula is expressed. Boolean formulas expressed in other ways are convertible to CNF.

Official documentation
The official GLPK documentation file <tt>doc/cnfsat.pdf</tt> contains a full reference for this feature. That material is therefore not repeated here. See obtaining GLPK.

Architecture
GLPK reads and writes CNF satisfiability problems in DIMACS format (see also GLPK format). Certain restrictions are placed on the problem specification so that it remains a valid CNF-SAT problem. These restrictions can be explicitly checked with the <tt>glp_check_cnfsat</tt> public call and are automatically confirmed when the GLPSOL <tt>--minisat</tt> option is deployed.

Within GLPK, CNF-SAT is considered a special case of MIP, where all the variables are binary and all the constraints are covering inequalities. That is, a particular CNF-SAT problem can be stored in a GLPK problem object of type <tt>glp_prob</tt> as if it were an MIP instance. This, in particular, means that a CNF-SAT problem can be solved with the <tt>glp_intopt</tt> solver, but that a call to <tt>glp_minisat1</tt> or <tt>glp_infeas1</tt>, being problem-specific, should be much more efficient.

In these latter cases, GLPK translates its MIP into a suitable format, calls the appropriate solver which then attempts to identify a feasible solution, and finally translates the solution back to the original problem instance for subsequent analysis and reporting.