\documentclass[a4paper,headings=small]{scrartcl} \usepackage[english]{babel} \usepackage[T1]{fontenc} \usepackage[latin1]{inputenc} \usepackage{textcomp,lmodern} \typearea[current]{last} \usepackage{fixltx2e,mparhack,mathdots} \usepackage{natbib} \usepackage{hyperref} \bibliographystyle{abbrvnat} \usepackage{microtype} \newcommand{\Comp}[1]{\texttt{#1}} \usepackage{dblfnote} \deffootnote[1.5em]{1.5em}{1em}{% \makebox[1.5em][l]{\scriptsize{\thefootnotemark}}% } \addtolength{\skip\footins}{0.5\baselineskip} \usepackage{fnpos} \hypersetup{ pdftitle = {glpkAPI -- Quick Start}, pdfauthor = {Gabriel Gelius-Dietrich}, pdfsubject = {R Interface to C API of GLPK}, pdfkeywords = {Optimization, GLPK}, pdfborder = {0 0 0}, pdfhighlight = {/N} } \newcommand{\pkg}[1]{\emph{#1}} \newcommand{\pkgname}{\pkg{glpkAPI}} \newcommand{\prgname}[1]{\textsc{#1}} \begin{document} \title{glpkAPI -- Quick Start} %\VignetteIndexEntry{Package glpkAPI -- Quick Start} \author{Gabriel Gelius-Dietrich} \maketitle \section{Introduction} The package \pkgname{} provides a low level interface to the C~API of \prgname{GLPK}\footnote{Andrew Makhorin: GNU Linear Programming Kit, Version~4.42 (or higher) \url{http://www.gnu.org/software/glpk/glpk.html}}, the GNU Linear Programming Kit. It is similar in purpose to the package \pkg{glpk}\footnote{Maintained by Lopaka Lee, available on \textsc{CRAN} \url{http://cran.r-project.org/package=glpk}}, but \pkgname{} relies on a separate installation of \prgname{GLPK}. \section{Installation} The package \pkgname{} depends on a working installation of \prgname{GLPK} (in particular libraries and header files). It is recommended to link \prgname{GLPK} to the GNU Multiple Precision Arithmetic Library Library (\prgname{GMP})\footnote{\url{http://gmplib.org/}} in order to gain more performance when using the exact simplex algorithm. See \Comp{INSTALL} for installation instructions and platform specific details. \textsc{CRAN}\footnote{\url{http://cran.r-project.org/}} provides binary versions of \pkgname{} for Windows and MacOS X, no other software is required here. \section{Usage} \subsection{Creating and solving a linear optimization problem} In the following, an example lp-problem will be created and solved. It is the same lp-problem which is used in the \prgname{GLPK} manual: \noindent \hspace{.5in} maximize \[ z = 10 x_1 + 6 x_2 + 4 x_3 \] \hspace{.5in} subject to \[ \begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}r} x_1 &+& x_2 &+& x_3 & \leq 100 \\ 10 x_1 &+& 4 x_2 &+& 5 x_3 & \leq 600 \\ 2 x_1 &+& 2 x_2 &+& 6 x_3 & \leq 300 \\ \end{array} \] With all variables being non-negative. \newpage \noindent Load the library. <<>>= library(glpkAPI) @ Create an empty problem object. <<>>= prob <- initProbGLPK() @ Assign a name to the problem object. <<>>= setProbNameGLPK(prob, "sample") @ Set the direction of optimization. The object \texttt{GLP\_MAX} is a predefined constant used by \prgname{GLPK}. A list of all available contants is written in the documentation \texttt{glpkConstants}. <<>>= setObjDirGLPK(prob, GLP_MAX) @ Add three rows and three colunms to the problem object. <<>>= addRowsGLPK(prob, 3) addColsGLPK(prob, 3) @ Set row and column names. <<>>= setRowNameGLPK(prob, 1, "p") setRowNameGLPK(prob, 2, "q") setRowNameGLPK(prob, 3, "r") setColNameGLPK(prob, 1, "x1") setColNameGLPK(prob, 2, "x2") setColNameGLPK(prob, 3, "x3") @ Set the type and bounds of the rows. <<>>= setRowBndGLPK(prob, 1, GLP_UP, 0, 100) setRowBndGLPK(prob, 2, GLP_UP, 0, 600) setRowBndGLPK(prob, 3, GLP_UP, 0, 300) @ Set the type and bounds of rows using a function which has the ability to work with vectors. <<>>= lb <- c(0, 0, 0) ub <- c(100, 600, 300) type <- rep(GLP_UP, 3) setRowsBndsGLPK(prob, 1:3, lb, ub, type) @ Set the type and bounds of the columns. <<>>= setColBndGLPK(prob, 1, GLP_LO, 0, 0) setColBndGLPK(prob, 2, GLP_LO, 0, 0) setColBndGLPK(prob, 3, GLP_LO, 0, 0) @ Set the objective function. <<>>= setObjCoefGLPK(prob, 1, 10) setObjCoefGLPK(prob, 2, 6) setObjCoefGLPK(prob, 3, 4) @ Set the type and bounds of columns and the objective function using a function which has the ability to work with vectors. <<>>= lb <- c(0, 0, 0) ub <- lb type <- rep(GLP_LO, 3) obj <- c(10, 6, 4) setColsBndsObjCoefsGLPK(prob, 1:3, lb, ub, obj, type) @ Load the constraint matrix. <<>>= ia <- c(1, 1, 1, 2, 3, 2, 3, 2, 3) ja <- c(1, 2, 3, 1, 1, 2, 2, 3, 3) ar <- c(1, 1, 1, 10, 2, 4, 2, 5, 6) loadMatrixGLPK(prob, 9, ia, ja, ar) @ Solve the problem using the simplex algorithm. <<>>= solveSimplexGLPK(prob) @ Retrieve the value of the objective function after optimization. <<>>= getObjValGLPK(prob) @ Retrieve the values of the structural variables (columns) after optimization. <<>>= getColPrimGLPK(prob, 1) getColPrimGLPK(prob, 2) getColPrimGLPK(prob, 3) @ Retrieve all primal values of the structural variables (columns) after optimization. <<>>= getColsPrimGLPK(prob) @ Retrieve all dual values of the structural variables (columns) after optimization (reduced costs). <<>>= getColsDualGLPK(prob) @ Print the solution to text file \texttt{sol.txt}. <<>>= printSolGLPK(prob, "sol.txt") @ Write the problem to file \texttt{prob.lp} in lp format. <<>>= writeLPGLPK(prob, "prob.lp") @ Read problem from file \texttt{prob.lp} in lp format. <<>>= lp <- initProbGLPK() readLPGLPK(lp, "prob.lp") @ Free memory, allacated to the problem object. <<>>= delProbGLPK(prob) delProbGLPK(lp) @ \subsection{Setting control prarmeters} All parameters and possible values are described in the documentation, see <<>>= help(glpkConstants) @ for details. The control parameters used by \pkgname{} have the same names like those from \prgname{GLPK}, except that they are written in capital letters. For example, the parameter \texttt{tm\_lim} in \prgname{GLPK} is \texttt{TM\_LIM} in \pkgname. The prarmeters are stored in a structure available only once per \prgname{R}~session. Set the searching time limit to one second. <<>>= setSimplexParmGLPK(TM_LIM, 1000) @ \section{Function names} \subsection{Searching} The function names in \pkgname{} are different from the names in \prgname{GLPK}, e.\,g. the function \texttt{addColsGLPK} in \pkgname{} is called \texttt{glp\_add\_cols} in \prgname{GLPK}. The directory \texttt{inst/} containes a file \texttt{c2r.map} which maps a \prgname{GLPK} function name to the corresponding \pkgname{} function name. Additionally, all man-pages contain an alias to the \prgname{GLPK} function name. The call <<>>= help("glp_add_cols") @ will bring up the man-page of \texttt{addColsGLPK}. Keep in mind that most of the \prgname{GLPK} functions do not work on vectors. For example the function \texttt{setColBndGLPK} (which is \texttt{glp\_set\_col\_bnds} in \prgname{GLPK}) sets the upper and lower bounds for exactly one column. The function \texttt{setColsBndsGLPK} in \pkgname{} can handle a vector of column indices. Assume, we have a problem containing 1000 columns and 600 rows, with all variables having a lower bound of zero and an upper bound of 25. The problem will be created as follows. <<>>= prob <- initProbGLPK() addColsGLPK(prob, 1000) addRowsGLPK(prob, 600) @ Now we can set the column bounds via \texttt{mapply} and \texttt{setColBndGLPK}. <<>>= system.time( mapply(setColBndGLPK, j = 1:1000, MoreArgs = list(lp = prob, type = GLP_DB, lb = 0, ub = 25)) ) @ Or we use the simpler call to \texttt{setColsBndsGLPK}. <<>>= system.time( setColsBndsGLPK(prob, j = 1:1000, type = rep(GLP_DB, 1000), lb = rep(0, 1000), ub = rep(0, 1000)) ) @ The latter call is also much faster. \subsection{Mapping} The file \texttt{c2r.map} in \texttt{inst/} maps the \pkgname{} function names to the orininal \prgname{GLPK} function names of its C-API. To use the latter, run <<>>= c2r <- system.file(package = "glpkAPI", "c2r.map") source(c2r) @ now either <<>>= pr1 <- initProbGLPK() delProbGLPK(pr1) @ or the original functions <<>>= pr2 <- glp_create_prob() glp_delete_prob(pr2) @ work both. Keep in mind that the mapping only affects the function names not the arguments of a function. \end{document}