\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}
