diff options
author | Pasha <pasha@member.fsf.org> | 2023-01-27 00:54:07 +0000 |
---|---|---|
committer | Pasha <pasha@member.fsf.org> | 2023-01-27 00:54:07 +0000 |
commit | ef800d4ffafdbde7d7a172ad73bd984b1695c138 (patch) | |
tree | 920cc189130f1e98f252283fce94851443641a6d /glpk-5.0/doc/glpk02.tex | |
parent | ec4ae3c2b5cb0e83fb667f14f832ea94f68ef075 (diff) | |
download | oneapi-ef800d4ffafdbde7d7a172ad73bd984b1695c138.tar.gz oneapi-ef800d4ffafdbde7d7a172ad73bd984b1695c138.tar.bz2 |
Diffstat (limited to 'glpk-5.0/doc/glpk02.tex')
-rw-r--r-- | glpk-5.0/doc/glpk02.tex | 3480 |
1 files changed, 3480 insertions, 0 deletions
diff --git a/glpk-5.0/doc/glpk02.tex b/glpk-5.0/doc/glpk02.tex new file mode 100644 index 0000000..f49ae75 --- /dev/null +++ b/glpk-5.0/doc/glpk02.tex @@ -0,0 +1,3480 @@ +%* glpk02.tex *% + +\chapter{Basic API Routines} + +\section{General conventions} + +\subsection{Library header} + +All GLPK API data types and routines are defined in the header file +\verb|glpk.h|. It should be included in all source files which use +GLPK API, either directly or indirectly through some other header file +as follows: + +\begin{verbatim} + #include <glpk.h> +\end{verbatim} + +\subsection{Error handling} + +If some GLPK API routine detects erroneous or incorrect data passed by +the application program, it writes appropriate diagnostic messages to +the terminal and then abnormally terminates the application program. +In most practical cases this allows to simplify programming by avoiding +numerous checks of return codes. Thus, in order to prevent crashing the +application program should check all data, which are suspected to be +incorrect, before calling GLPK API routines. + +Should note that this kind of error handling is used only in cases of +incorrect data passed by the application program. If, for example, the +application program calls some GLPK API routine to read data from an +input file and these data are incorrect, the GLPK API routine reports +about error in the usual way by means of the return code. + +\subsection{Thread safety} + +The standard version of GLPK API is {\it not} thread safe and therefore +should not be used in multi-threaded programs. + +\subsection{Array indexing} + +Normally all GLPK API routines start array indexing from 1, not from 0 +(except the specially stipulated cases). This means, for example, that +if some vector $x$ of the length $n$ is passed as an array to some GLPK +API routine, the latter expects vector components to be placed in +locations \verb|x[1]|, \verb|x[2]|, \dots, \verb|x[n]|, and the +location \verb|x[0]| normally is not used. + +To avoid indexing errors it is most convenient and most reliable to +declare the array \verb|x| as follows: + +\begin{verbatim} + double x[1+n]; +\end{verbatim} + +\noindent +or to allocate it as follows: + +\begin{verbatim} + double *x; + . . . + x = calloc(1+n, sizeof(double)); + . . . +\end{verbatim} + +\noindent +In both cases one extra location \verb|x[0]| is reserved that allows +passing the array to GLPK routines in a usual way. + +\section{Problem object} + +All GLPK API routines deal with so called {\it problem object}, which +is a program object of type \verb|glp_prob| and intended to represent +a particular LP or MIP instance. + +The type \verb|glp_prob| is a data structure declared in the header +file \verb|glpk.h| as follows: + +\begin{verbatim} + typedef struct glp_prob glp_prob; +\end{verbatim} + +Problem objects (i.e. program objects of the \verb|glp_prob| type) are +allocated and managed internally by the GLPK API routines. The +application program should never use any members of the \verb|glp_prob| +structure directly and should deal only with pointers to these objects +(that is, \verb|glp_prob *| values). + +The problem object consists of the following segments: + +%\vspace*{-8pt} + +%\begin{itemize}\setlength{\itemsep}{0pt} +\Item{---}problem segment, + +\Item{---}basis segment, + +\Item{---}interior-point segment, and + +\Item{---}MIP segment. +%\end{itemize} + +\subsection{Problem segment} + +The {\it problem segment} contains original LP/MIP data, which +corresponds to the problem formulation (1.1)---(1.3) (see Section +\ref{seclp}, page \pageref{seclp}). This segment includes the following +components: + +%\vspace*{-8pt} + +%\begin{itemize}\setlength{\itemsep}{0pt} +\Item{---}rows (auxiliary variables), + +\Item{---}columns (structural variables), + +\Item{---}objective function, and + +\Item{---}constraint matrix. +%\end{itemize} + +%\vspace*{-7pt} + +Rows and columns have the same set of the following attributes: + +%\vspace*{-7pt} + +%\begin{itemize}\setlength{\itemsep}{0pt} +\Item{---}ordinal number, + +\Item{---}symbolic name (1 up to 255 arbitrary graphic characters), + +\Item{---}type (free, lower bound, upper bound, double bound, fixed), + +\Item{---}numerical values of lower and upper bounds, + +\Item{---}scale factor. +%\end{itemize} + +%\vspace*{-7pt} + +{\it Ordinal numbers} are intended for referencing rows and columns. +Row ordinal numbers are integers $1, 2, \dots, m$, and column ordinal +numbers are integers $1, 2, \dots, n$, where $m$ and $n$ are, +respectively, the current number of rows and columns in the problem +object. + +{\it Symbolic names} are intended for informational purposes. They also +can be used for referencing rows and columns. + +{\it Types and bounds} of rows (auxiliary variables) and columns +(structural variables) are explained above (see Section \ref{seclp}, +page \pageref{seclp}). + +{\it Scale factors} are used internally for scaling rows and columns of +the constraint matrix. + +Information about the {\it objective function} includes numerical +values of objective coefficients and a flag, which defines the +optimization direction (i.e. minimization or maximization). + +The {\it constraint matrix} is a $m \times n$ rectangular matrix built +of constraint coefficients $a_{ij}$, which defines the system of linear +constraints (1.2) (see Section \ref{seclp}, page \pageref{seclp}). This +matrix is stored in the problem object in both row-wise and column-wise +sparse formats. + +Once the problem object has been created, the application program can +access and modify any components of the problem segment in arbitrary +order. + +\subsection{Basis segment} + +The {\it basis segment} of the problem object keeps information related +to the current basic solution. It includes: + +%\vspace*{-8pt} + +%\begin{itemize}\setlength{\itemsep}{0pt} +\Item{---}row and column statuses, + +\Item{---}basic solution statuses, + +\Item{---}factorization of the current basis matrix, and + +\Item{---}basic solution components. +%\end{itemize} + +%\vspace*{-8pt} + +The {\it row and column statuses} define which rows and columns are +basic and which are non-basic. These statuses may be assigned either by +the application program of by some API routines. Note that these +statuses are always defined independently on whether the corresponding +basis is valid or not. + +The {\it basic solution statuses} include the {\it primal status} and +the {\it dual status}, which are set by the simplex-based solver once +the problem has been solved. The primal status shows whether a primal +basic solution is feasible, infeasible, or undefined. The dual status +shows the same for a dual basic solution. + +The {\it factorization of the basis matrix} is some factorized form +(like {\it LU}-factorization) of the current basis matrix (defined by +the current row and column statuses). The factorization is used by +simplex-based solvers and kept when the solver terminates the search. +This feature allows efficiently reoptimizing the problem after some +modifications (for example, after changing some bounds or objective +coefficients). It also allows performing the post-optimal analysis (for +example, computing components of the simplex table, etc.). + +The {\it basic solution components} include primal and dual values of +all auxiliary and structural variables for the most recently obtained +basic solution. + +\subsection{Interior-point segment} + +The {\it interior-point segment} contains interior-point solution +components, which include the solution status, and primal and dual +values of all auxiliary and structural variables. + +\subsection{MIP segment} + +The {\it MIP segment} is used only for MIP problems. This segment +includes: + +%\vspace*{-8pt} + +%\begin{itemize}\setlength{\itemsep}{0pt} +\Item{---}column kinds, + +\Item{---}MIP solution status, and + +\Item{---}MIP solution components. +%\end{itemize} + +%\vspace*{-8pt} + +The {\it column kinds} define which columns (i.e. structural variables) +are integer and which are continuous. + +The {\it MIP solution status} is set by the MIP solver and shows whether +a MIP solution is integer optimal, integer feasible (non-optimal), or +undefined. + +The {\it MIP solution components} are computed by the MIP solver and +include primal values of all auxiliary and structural variables for the +most recently obtained MIP solution. + +Note that in case of MIP problem the basis segment corresponds to +the optimal solution of LP relaxation, which is also available to the +application program. + +Currently the search tree is not kept in the MIP segment, so if the +search has been terminated, it cannot be continued. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Problem creating and modifying routines} + +\subsection{glp\_create\_prob --- create problem object} + +\synopsis + +\begin{verbatim} + glp_prob *glp_create_prob(void); +\end{verbatim} + +\description + +The routine \verb|glp_create_prob| creates a new problem object, which +initially is ``empty'', i.e. has no rows and columns. + +\returns + +The routine returns a pointer to the created object, which should be +used in any subsequent operations on this object. + +\subsection{glp\_set\_prob\_name --- assign (change) problem name} + +\synopsis + +\begin{verbatim} + void glp_set_prob_name(glp_prob *P, const char *name); +\end{verbatim} + +\description + +The routine \verb|glp_set_prob_name| assigns a given symbolic +\verb|name| (1 up to 255 characters) to the specified problem object. + +If the parameter \verb|name| is \verb|NULL| or empty string, the +routine erases an existing symbolic name of the problem object. + +\subsection{glp\_set\_obj\_name --- assign (change) objective function +name} + +\synopsis + +\begin{verbatim} + void glp_set_obj_name(glp_prob *P, const char *name); +\end{verbatim} + +\description + +The routine \verb|glp_set_obj_name| assigns a given symbolic +\verb|name| (1 up to 255 characters) to the objective function of the +specified problem object. + +If the parameter \verb|name| is \verb|NULL| or empty string, the +routine erases an existing symbolic name of the objective function. + +\newpage + +\subsection{glp\_set\_obj\_dir --- set (change) optimization direction +flag} + +\synopsis + +\begin{verbatim} + void glp_set_obj_dir(glp_prob *P, int dir); +\end{verbatim} + +\description + +The routine \verb|glp_set_obj_dir| sets (changes) the optimization +direction flag (i.e. ``sense'' of the objective function) as specified +by the parameter \verb|dir|: + +\verb|GLP_MIN| means minimization; + +\verb|GLP_MAX| means maximization. + +Note that by default the problem is minimization. + +\subsection{glp\_add\_rows --- add new rows to problem object} + +\synopsis + +\begin{verbatim} + int glp_add_rows(glp_prob *P, int nrs); +\end{verbatim} + +\description + +The routine \verb|glp_add_rows| adds \verb|nrs| rows (constraints) to +the specified problem object. New rows are always added to the end of +the row list, so the ordinal numbers of existing rows are not changed. + +Being added each new row is initially free (unbounded) and has empty +list of the constraint coefficients. + +Each new row becomes a non-active (non-binding) constraint, i.e. the +corresponding auxiliary variable is marked as basic. + +If the basis factorization exists, adding row(s) invalidates it. + +\returns + +The routine \verb|glp_add_rows| returns the ordinal number of the first +new row added to the problem object. + +\subsection{glp\_add\_cols --- add new columns to problem object} + +\synopsis + +\begin{verbatim} + int glp_add_cols(glp_prob *P, int ncs); +\end{verbatim} + +\description + +The routine \verb|glp_add_cols| adds \verb|ncs| columns (structural +variables) to the specified problem object. New columns are always +added to the end of the column list, so the ordinal numbers of existing +columns are not changed. + +Being added each new column is initially fixed at zero and has empty +list of the constraint coefficients. + +Each new column is marked as non-basic, i.e. zero value of the +corresponding structural variable becomes an active (binding) bound. + +If the basis factorization exists, it remains valid. + +\returns + +The routine \verb|glp_add_cols| returns the ordinal number of the first +new column added to the problem object. + +\subsection{glp\_set\_row\_name --- assign (change) row name} + +\synopsis + +\begin{verbatim} + void glp_set_row_name(glp_prob *P, int i, const char *name); +\end{verbatim} + +\description + +The routine \verb|glp_set_row_name| assigns a given symbolic +\verb|name| (1 up to 255 characters) to \verb|i|-th row (auxiliary +variable) of the specified problem object. + +If the parameter \verb|name| is \verb|NULL| or empty string, the +routine erases an existing name of $i$-th row. + +\subsection{glp\_set\_col\_name --- assign (change) column name} + +\synopsis + +\begin{verbatim} + void glp_set_col_name(glp_prob *P, int j, const char *name); +\end{verbatim} + +\description + +The routine \verb|glp_set_col_name| assigns a given symbolic +\verb|name| (1 up to 255 characters) to \verb|j|-th column (structural +variable) of the specified problem object. + +If the parameter \verb|name| is \verb|NULL| or empty string, the +routine erases an existing name of $j$-th column. + +\subsection{glp\_set\_row\_bnds --- set (change) row bounds} + +\synopsis + +{\tt void glp\_set\_row\_bnds(glp\_prob *P, int i, int type, +double lb, double ub);} + +\description + +The routine \verb|glp_set_row_bnds| sets (changes) the type and bounds +of \verb|i|-th row (auxiliary variable) of the specified problem +object. + +The parameters \verb|type|, \verb|lb|, and \verb|ub| specify the type, +lower bound, and upper bound, respectively, as follows: + +\begin{center} +\begin{tabular}{cr@{}c@{}ll} +Type & \multicolumn{3}{c}{Bounds} & Comment \\ +\hline +\verb|GLP_FR| & $-\infty <$ &$\ x\ $& $< +\infty$ + & Free (unbounded) variable \\ +\verb|GLP_LO| & $lb \leq$ &$\ x\ $& $< +\infty$ + & Variable with lower bound \\ +\verb|GLP_UP| & $-\infty <$ &$\ x\ $& $\leq ub$ + & Variable with upper bound \\ +\verb|GLP_DB| & $lb \leq$ &$\ x\ $& $\leq ub$ + & Double-bounded variable \\ +\verb|GLP_FX| & $lb =$ &$\ x\ $& $= ub$ + & Fixed variable \\ +\end{tabular} +\end{center} + +\noindent +where $x$ is the auxiliary variable associated with $i$-th row. + +If the row has no lower bound, the parameter \verb|lb| is ignored. If +the row has no upper bound, the parameter \verb|ub| is ignored. If the +row is an equality constraint (i.e. the corresponding auxiliary +variable is of fixed type), only the parameter \verb|lb| is used while +the parameter \verb|ub| is ignored. + +Being added to the problem object each row is initially free, i.e. its +type is \verb|GLP_FR|. + +\subsection{glp\_set\_col\_bnds --- set (change) column bounds} + +\synopsis + +{\tt void glp\_set\_col\_bnds(glp\_prob *P, int j, int type, +double lb, double ub);} + +\description + +The routine \verb|glp_set_col_bnds| sets (changes) the type and bounds +of \verb|j|-th column (structural variable) of the specified problem +object. + +The parameters \verb|type|, \verb|lb|, and \verb|ub| specify the type, +lower bound, and upper bound, respectively, as follows: + +\begin{center} +\begin{tabular}{cr@{}c@{}ll} +Type & \multicolumn{3}{c}{Bounds} & Comment \\ +\hline +\verb|GLP_FR| & $-\infty <$ &$\ x\ $& $< +\infty$ + & Free (unbounded) variable \\ +\verb|GLP_LO| & $lb \leq$ &$\ x\ $& $< +\infty$ + & Variable with lower bound \\ +\verb|GLP_UP| & $-\infty <$ &$\ x\ $& $\leq ub$ + & Variable with upper bound \\ +\verb|GLP_DB| & $lb \leq$ &$\ x\ $& $\leq ub$ + & Double-bounded variable \\ +\verb|GLP_FX| & $lb =$ &$\ x\ $& $= ub$ + & Fixed variable \\ +\end{tabular} +\end{center} + +\noindent +where $x$ is the structural variable associated with $j$-th column. + +If the column has no lower bound, the parameter \verb|lb| is ignored. +If the column has no upper bound, the parameter \verb|ub| is ignored. +If the column is of fixed type, only the parameter \verb|lb| is used +while the parameter \verb|ub| is ignored. + +Being added to the problem object each column is initially fixed at +zero, i.e. its type is \verb|GLP_FX| and both bounds are 0. + +%\newpage + +\subsection{glp\_set\_obj\_coef --- set (change) objective coefficient +or constant term} + +\synopsis + +\begin{verbatim} + void glp_set_obj_coef(glp_prob *P, int j, double coef); +\end{verbatim} + +\description + +The routine \verb|glp_set_obj_coef| sets (changes) the objective +coefficient at \verb|j|-th column (structural variable). A new value of +the objective coefficient is specified by the parameter \verb|coef|. + +If the parameter \verb|j| is 0, the routine sets (changes) the constant +term (``shift'') of the objective function. + +\newpage + +\subsection{glp\_set\_mat\_row --- set (replace) row of the constraint +matrix} + +\synopsis + +\begin{verbatim} + void glp_set_mat_row(glp_prob *P, int i, int len, const int ind[], + const double val[]); +\end{verbatim} + +\description + +The routine \verb|glp_set_mat_row| stores (replaces) the contents of +\verb|i|-th row of the constraint matrix of the specified problem +object. + +Column indices and numerical values of new row elements should be +placed in locations\linebreak \verb|ind[1]|, \dots, \verb|ind[len]| and +\verb|val[1]|, \dots, \verb|val[len]|, respectively, where +$0 \leq$ \verb|len| $\leq n$ is the new length of $i$-th row, $n$ is +the current number of columns in the problem object. Elements with +identical column indices are not allowed. Zero elements are allowed, +but they are not stored in the constraint matrix. + +If the parameter \verb|len| is 0, the parameters \verb|ind| and/or +\verb|val| can be specified as \verb|NULL|. + +\note + +If the basis factorization exists and changing the row changes +coefficients at basic column(s), the factorization is invalidated. + +\subsection{glp\_set\_mat\_col --- set (replace) column of the +constr\-aint matrix} + +\synopsis + +\begin{verbatim} + void glp_set_mat_col(glp_prob *P, int j, int len, const int ind[], + const double val[]); +\end{verbatim} + +\description + +The routine \verb|glp_set_mat_col| stores (replaces) the contents of +\verb|j|-th column of the constraint matrix of the specified problem +object. + +Row indices and numerical values of new column elements should be +placed in locations\linebreak \verb|ind[1]|, \dots, \verb|ind[len]| and +\verb|val[1]|, \dots, \verb|val[len]|, respectively, where +$0 \leq$ \verb|len| $\leq m$ is the new length of $j$-th column, $m$ is +the current number of rows in the problem object. Elements with +identical row indices are not allowed. Zero elements are allowed, but +they are not stored in the constraint matrix. + +If the parameter \verb|len| is 0, the parameters \verb|ind| and/or +\verb|val| can be specified as \verb|NULL|. + +\note + +If the basis factorization exists, changing the column corresponding +to a basic structural variable invalidates it. + +\newpage + +\subsection{glp\_load\_matrix --- load (replace) the whole constraint +matrix} + +\synopsis + +\begin{verbatim} + void glp_load_matrix(glp_prob *P, int ne, const int ia[], + const int ja[], const double ar[]); +\end{verbatim} + +\description + +The routine \verb|glp_load_matrix| loads the constraint matrix passed +in the arrays \verb|ia|, \verb|ja|, and \verb|ar| into the specified +problem object. Before loading the current contents of the constraint +matrix is destroyed. + +Constraint coefficients (elements of the constraint matrix) should be +specified as triplets (\verb|ia[k]|, \verb|ja[k]|, \verb|ar[k]|) for +$k=1,\dots,ne$, where \verb|ia[k]| is the row index, \verb|ja[k]| is +the column index, and \verb|ar[k]| is a numeric value of corresponding +constraint coefficient. The parameter \verb|ne| specifies the total +number of (non-zero) elements in the matrix to be loaded. Coefficients +with identical indices are not allowed. Zero coefficients are allowed, +however, they are not stored in the constraint matrix. + +If the parameter \verb|ne| is 0, the parameters \verb|ia|, \verb|ja|, +and/or \verb|ar| can be specified as \verb|NULL|. + +\note + +If the basis factorization exists, this operation invalidates it. + +\subsection{glp\_check\_dup --- check for duplicate elements in sparse +matrix} + +\synopsis + +{\tt int glp\_check\_dup(int m, int n, int ne, const int ia[], +const int ja[]);} + +\description + +The routine \verb|glp_check_dup checks| for duplicate elements (that +is, elements with identical indices) in a sparse matrix specified in +the coordinate format. + +The parameters $m$ and $n$ specifies, respectively, the number of rows +and columns in the matrix, $m\geq 0$, $n\geq 0$. + +The parameter {\it ne} specifies the number of (structurally) non-zero +elements in the matrix,\linebreak {\it ne} $\geq 0$. + +Elements of the matrix are specified as doublets $(ia[k],ja[k])$ for +$k=1,\dots,ne$, where $ia[k]$ is a row index, $ja[k]$ is a column +index. + +The routine \verb|glp_check_dup| can be used prior to a call to the +routine \verb|glp_load_matrix| to check that the constraint matrix to +be loaded has no duplicate elements. + +\returns + +\begin{retlist} +0& the matrix representation is correct;\\ +$-k$& indices $ia[k]$ or/and $ja[k]$ are out of range;\\ +$+k$& element $(ia[k],ja[k])$ is duplicate.\\ +\end{retlist} + +\subsection{glp\_sort\_matrix --- sort elements of the constraint +matrix} + +\synopsis + +\begin{verbatim} + void glp_sort_matrix(glp_prob *P); +\end{verbatim} + +\description + +The routine \verb|glp_sort_matrix| sorts elements of the constraint +matrix by rebuilding its row and column linked lists. + +On exit from the routine the constraint matrix is not changed, however, +elements in the row linked lists become ordered by ascending column +indices, and the elements in the column linked lists become ordered by +ascending row indices. + +\subsection{glp\_del\_rows --- delete rows from problem object} + +\synopsis + +\begin{verbatim} + void glp_del_rows(glp_prob *P, int nrs, const int num[]); +\end{verbatim} + +\description + +The routine \verb|glp_del_rows| deletes rows from the specified problem +object. Ordinal numbers of rows to be deleted should be placed in +locations \verb|num[1]|, \dots, \verb|num[nrs]|, where ${\tt nrs}>0$. + +Note that deleting rows involves changing ordinal numbers of other +rows remaining in the problem object. New ordinal numbers of the +remaining rows are assigned under the assumption that the original +order of rows is not changed. Let, for example, before deletion there +be five rows $a$, $b$, $c$, $d$, $e$ with ordinal numbers 1, 2, 3, 4, +5, and let rows $b$ and $d$ have been deleted. Then after deletion the +remaining rows $a$, $c$, $e$ are assigned new oridinal numbers 1, 2, 3. + +If the basis factorization exists, deleting active (binding) rows, +i.e. whose auxiliary variables are marked as non-basic, invalidates it. + +%\newpage + +\subsection{glp\_del\_cols --- delete columns from problem object} + +\synopsis + +\begin{verbatim} + void glp_del_cols(glp_prob *P, int ncs, const int num[]); +\end{verbatim} + +\description + +The routine \verb|glp_del_cols| deletes columns from the specified +problem object. Ordinal numbers of columns to be deleted should be +placed in locations \verb|num[1]|, \dots, \verb|num[ncs]|, where +${\tt ncs}>0$. + +Note that deleting columns involves changing ordinal numbers of other +columns remaining in\linebreak the problem object. New ordinal numbers +of the remaining columns are assigned under the assumption that the +original order of columns is not changed. Let, for example, before +deletion there be six columns $p$, $q$, $r$, $s$, $t$, $u$ with +ordinal numbers 1, 2, 3, 4, 5, 6, and let columns $p$, $q$, $s$ have +been deleted. Then after deletion the remaining columns $r$, $t$, $u$ +are assigned new ordinal numbers 1, 2, 3. + +If the basis factorization exists, deleting basic columns invalidates +it. + +\subsection{glp\_copy\_prob --- copy problem object content} + +\synopsis + +\begin{verbatim} + void glp_copy_prob(glp_prob *dest, glp_prob *prob, int names); +\end{verbatim} + +\description + +The routine \verb|glp_copy_prob| copies the content of the problem +object \verb|prob| to the problem object \verb|dest|. + +The parameter \verb|names| is a flag. If it is \verb|GLP_ON|, +the routine also copies all symbolic names; otherwise, if it is +\verb|GLP_OFF|, no symbolic names are copied. + +\subsection{glp\_erase\_prob --- erase problem object content} + +\synopsis + +\begin{verbatim} + void glp_erase_prob(glp_prob *P); +\end{verbatim} + +\description + +The routine \verb|glp_erase_prob| erases the content of the specified +problem object. The effect of this operation is the same as if the +problem object would be deleted with the routine \verb|glp_delete_prob| +and then created anew with the routine \verb|glp_create_prob|, with the +only exception that the pointer to the problem object remains valid. + +%\newpage + +\subsection{glp\_delete\_prob --- delete problem object} + +\synopsis + +\begin{verbatim} + void glp_delete_prob(glp_prob *P); +\end{verbatim} + +\description + +The routine \verb|glp_delete_prob| deletes a problem object, which the +parameter \verb|lp| points to, freeing all the memory allocated to this +object. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Problem retrieving routines} + +\subsection{glp\_get\_prob\_name --- retrieve problem name} + +\synopsis + +\begin{verbatim} + const char *glp_get_prob_name(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_prob_name| returns a pointer to an internal +buffer, which contains symbolic name of the problem. However, if the +problem has no assigned name, the routine returns \verb|NULL|. + +\subsection{glp\_get\_obj\_name --- retrieve objective function name} + +\synopsis + +\begin{verbatim} + const char *glp_get_obj_name(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_obj_name| returns a pointer to an internal +buffer, which contains symbolic name assigned to the objective +function. However, if the objective function has no assigned name, the +routine returns \verb|NULL|. + +\subsection{glp\_get\_obj\_dir --- retrieve optimization direction +flag} + +\synopsis + +\begin{verbatim} + int glp_get_obj_dir(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_obj_dir| returns the optimization direction +flag (i.e. ``sense'' of the objective function): + +\verb|GLP_MIN| means minimization; + +\verb|GLP_MAX| means maximization. + +\subsection{glp\_get\_num\_rows --- retrieve number of rows} + +\synopsis + +\begin{verbatim} + int glp_get_num_rows(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_num_rows| returns the current number of rows +in the specified problem object. + +\newpage + +\subsection{glp\_get\_num\_cols --- retrieve number of columns} + +\synopsis + +\begin{verbatim} + int glp_get_num_cols(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_num_cols| returns the current number of +columns in the specified problem object. + +\subsection{glp\_get\_row\_name --- retrieve row name} + +\synopsis + +\begin{verbatim} + const char *glp_get_row_name(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_get_row_name| returns a pointer to an internal +buffer, which contains a symbolic name assigned to \verb|i|-th row. +However, if the row has no assigned name, the routine returns +\verb|NULL|. + +\subsection{glp\_get\_col\_name --- retrieve column name} + +\synopsis + +\begin{verbatim} + const char *glp_get_col_name(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_get_col_name| returns a pointer to an internal +buffer, which contains a symbolic name assigned to \verb|j|-th column. +However, if the column has no assigned name, the routine returns +\verb|NULL|. + +\subsection{glp\_get\_row\_type --- retrieve row type} + +\synopsis + +\begin{verbatim} + int glp_get_row_type(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_get_row_type| returns the type of \verb|i|-th +row, i.e. the type of corresponding auxiliary variable, as follows: + +\verb|GLP_FR| --- free (unbounded) variable; + +\verb|GLP_LO| --- variable with lower bound; + +\verb|GLP_UP| --- variable with upper bound; + +\verb|GLP_DB| --- double-bounded variable; + +\verb|GLP_FX| --- fixed variable. + +\subsection{glp\_get\_row\_lb --- retrieve row lower bound} + +\synopsis + +\begin{verbatim} + double glp_get_row_lb(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_get_row_lb| returns the lower bound of +\verb|i|-th row, i.e. the lower bound of corresponding auxiliary +variable. However, if the row has no lower bound, the routine returns +\verb|-DBL_MAX|. + +\vspace*{-4pt} + +\subsection{glp\_get\_row\_ub --- retrieve row upper bound} + +\synopsis + +\begin{verbatim} + double glp_get_row_ub(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_get_row_ub| returns the upper bound of +\verb|i|-th row, i.e. the upper bound of corresponding auxiliary +variable. However, if the row has no upper bound, the routine returns +\verb|+DBL_MAX|. + +\vspace*{-4pt} + +\subsection{glp\_get\_col\_type --- retrieve column type} + +\synopsis + +\begin{verbatim} + int glp_get_col_type(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_get_col_type| returns the type of \verb|j|-th +column, i.e. the type of corresponding structural variable, as follows: + +\verb|GLP_FR| --- free (unbounded) variable; + +\verb|GLP_LO| --- variable with lower bound; + +\verb|GLP_UP| --- variable with upper bound; + +\verb|GLP_DB| --- double-bounded variable; + +\verb|GLP_FX| --- fixed variable. + +\vspace*{-4pt} + +\subsection{glp\_get\_col\_lb --- retrieve column lower bound} + +\synopsis + +\begin{verbatim} + double glp_get_col_lb(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_get_col_lb| returns the lower bound of +\verb|j|-th column, i.e. the lower bound of corresponding structural +variable. However, if the column has no lower bound, the routine +returns \verb|-DBL_MAX|. + +\subsection{glp\_get\_col\_ub --- retrieve column upper bound} + +\synopsis + +\begin{verbatim} + double glp_get_col_ub(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_get_col_ub| returns the upper bound of +\verb|j|-th column, i.e. the upper bound of corresponding structural +variable. However, if the column has no upper bound, the routine +returns \verb|+DBL_MAX|. + +\subsection{glp\_get\_obj\_coef --- retrieve objective coefficient or +constant term} + +\synopsis + +\begin{verbatim} + double glp_get_obj_coef(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_get_obj_coef| returns the objective coefficient +at \verb|j|-th structural variable (column). + +If the parameter \verb|j| is 0, the routine returns the constant term +(``shift'') of the objective function. + +\subsection{glp\_get\_num\_nz --- retrieve number of constraint +coefficients} + +\synopsis + +\begin{verbatim} + int glp_get_num_nz(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_num_nz| returns the number of non-zero +elements in the constraint matrix of the specified problem object. + +\subsection{glp\_get\_mat\_row --- retrieve row of the constraint +matrix} + +\synopsis + +\begin{verbatim} + int glp_get_mat_row(glp_prob *P, int i, int ind[], double val[]); +\end{verbatim} + +\description + +The routine \verb|glp_get_mat_row| scans (non-zero) elements of +\verb|i|-th row of the constraint matrix of the specified problem +object and stores their column indices and numeric values to locations +\verb|ind[1]|, \dots, \verb|ind[len]| and \verb|val[1]|, \dots, +\verb|val[len]|, respectively, where $0\leq{\tt len}\leq n$ is the +number of elements in $i$-th row, $n$ is the number of columns. + +The parameter \verb|ind| and/or \verb|val| can be specified as +\verb|NULL|, in which case corresponding information is not stored. + +%\newpage + +\returns + +The routine \verb|glp_get_mat_row| returns the length \verb|len|, i.e. +the number of (non-zero) elements in \verb|i|-th row. + +\subsection{glp\_get\_mat\_col --- retrieve column of the constraint +matrix} + +\synopsis + +\begin{verbatim} + int glp_get_mat_col(glp_prob *P, int j, int ind[], double val[]); +\end{verbatim} + +\description + +The routine \verb|glp_get_mat_col| scans (non-zero) elements of +\verb|j|-th column of the constraint matrix of the specified problem +object and stores their row indices and numeric values to locations +\linebreak \verb|ind[1]|, \dots, \verb|ind[len]| and \verb|val[1]|, +\dots, \verb|val[len]|, respectively, where $0\leq{\tt len}\leq m$ is +the number of elements in $j$-th column, $m$ is the number of rows. + +The parameter \verb|ind| and/or \verb|val| can be specified as +\verb|NULL|, in which case corresponding information is not stored. + +\returns + +The routine \verb|glp_get_mat_col| returns the length \verb|len|, i.e. +the number of (non-zero) elements in \verb|j|-th column. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Row and column searching routines} + +Sometimes it may be necessary to find rows and/or columns by their +names (assigned with the routines \verb|glp_set_row_name| and +\verb|glp_set_col_name|). Though a particular row/column can be found +by its name using simple enumeration of all rows/columns, in case of +large instances such a {\it linear} search may take too long time. + +To significantly reduce the search time the application program may +create the row/column name index, which is an auxiliary data structure +implementing a {\it binary} search. Even in worst cases the search +takes logarithmic time, i.e. the time needed to find a particular row +(or column) by its name is $O(\log_2m)$ (or $O(\log_2n)$), where $m$ +and $n$ are, resp., the number of rows and columns in the problem +object. + +It is important to note that: + +\Item{1.}On creating the problem object with the routine +\verb|glp_create_prob| the name index is {\it not} created. + +\Item{2.}The name index can be created (destroyed) at any time with the +routine \verb|glp_create_index| (\verb|glp_delete_index|). Having been +created the name index becomes part of the corresponding problem +object. + +\Item{3.}The time taken to create the name index is +$O[(m+n)\log_2(m+n)]$, so it is recommended to create the index only +once, for example, just after the problem object was created. + +\Item{4.}If the name index exists, it is automatically updated every +time the name of a row/column is assigned/changed. The update operation +takes logarithmic time. + +\Item{5.}If the name index does not exist, the application should not +call the routines \verb|glp_find_row| and \verb|glp_find_col|. +Otherwise, an error message will be issued and abnormal program +termination will occur. + +\Item{6.}On destroying the problem object with the routine +\verb|glp_delete_prob|, the name index, if exists, is automatically +destroyed. + +\subsection{glp\_create\_index --- create the name index} + +\synopsis + +\begin{verbatim} + void glp_create_index(glp_prob *P); +\end{verbatim} + +\description + +The routine \verb|glp_create_index| creates the name index for the +specified problem object. The name index is an auxiliary data +structure, which is intended to quickly (i.e. for logarithmic time) +find rows and columns by their names. + +This routine can be called at any time. If the name index already +exists, the routine does nothing. + +\newpage + +\subsection{glp\_find\_row --- find row by its name} + +\synopsis + +\begin{verbatim} + int glp_find_row(glp_prob *P, const char *name); +\end{verbatim} + +\returns + +The routine \verb|glp_find_row| returns the ordinal number of a row, +which is assigned the specified symbolic \verb|name|. If no such row +exists, the routine returns 0. + +\subsection{glp\_find\_col --- find column by its name} + +\synopsis + +\begin{verbatim} + int glp_find_col(glp_prob *P, const char *name); +\end{verbatim} + +\returns + +The routine \verb|glp_find_col| returns the ordinal number of a column, +which is assigned the specified symbolic \verb|name|. If no such column +exists, the routine returns 0. + +\subsection{glp\_delete\_index --- delete the name index} + +\synopsis + +\begin{verbatim} + void glp_delete_index(glp_prob *P); +\end{verbatim} + +\description + +The routine \verb|glp_delete_index| deletes the name index previously +created by the routine\linebreak \verb|glp_create_index| and frees the +memory allocated to this auxiliary data structure. + +This routine can be called at any time. If the name index does not +exist, the routine does nothing. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Problem scaling routines} + +\subsection{Background} + +In GLPK the {\it scaling} means a linear transformation applied to the +constraint matrix to improve its numerical properties.\footnote{In many +cases a proper scaling allows making the constraint matrix to be better +conditioned, i.e. decreasing its condition number, that makes +computations numerically more stable.} + +The main equality is the following: +$$\widetilde{A}=RAS,\eqno(2.1)$$ +where $A=(a_{ij})$ is the original constraint matrix, $R=(r_{ii})>0$ is +a diagonal matrix used to scale rows (constraints), $S=(s_{jj})>0$ is a +diagonal matrix used to scale columns (variables), $\widetilde{A}$ is +the scaled constraint matrix. + +From (2.1) it follows that in the {\it scaled} problem instance each +original constraint coefficient $a_{ij}$ is replaced by corresponding +scaled constraint coefficient: +$$\widetilde{a}_{ij}=r_{ii}a_{ij}s_{jj}.\eqno(2.2)$$ + +Note that the scaling is performed internally and therefore +transparently to the user. This means that on API level the user always +deal with unscaled data. + +Scale factors $r_{ii}$ and $s_{jj}$ can be set or changed at any time +either directly by the application program in a problem specific way +(with the routines \verb|glp_set_rii| and \verb|glp_set_sjj|), or by +some API routines intended for automatic scaling. + +\subsection{glp\_set\_rii --- set (change) row scale factor} + +\synopsis + +\begin{verbatim} + void glp_set_rii(glp_prob *P, int i, double rii); +\end{verbatim} + +\description + +The routine \verb|glp_set_rii| sets (changes) the scale factor $r_{ii}$ +for $i$-th row of the specified problem object. + +\subsection{glp\_set\_sjj --- set (change) column scale factor} + +\synopsis + +\begin{verbatim} + void glp_set_sjj(glp_prob *P, int j, double sjj); +\end{verbatim} + +\description + +The routine \verb|glp_set_sjj| sets (changes) the scale factor $s_{jj}$ +for $j$-th column of the specified problem object. + +\newpage + +\subsection{glp\_get\_rii --- retrieve row scale factor} + +\synopsis + +\begin{verbatim} + double glp_get_rii(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_get_rii| returns current scale factor $r_{ii}$ +for $i$-th row of the specified problem object. + +\vspace*{-6pt} + +\subsection{glp\_get\_sjj --- retrieve column scale factor} + +\vspace*{-4pt} + +\synopsis + +\begin{verbatim} + double glp_get_sjj(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_get_sjj| returns current scale factor $s_{jj}$ +for $j$-th column of the specified problem object. + +\vspace*{-6pt} + +\subsection{glp\_scale\_prob --- scale problem data} + +\vspace*{-4pt} + +\synopsis + +\begin{verbatim} + void glp_scale_prob(glp_prob *P, int flags); +\end{verbatim} + +\description + +The routine \verb|glp_scale_prob| performs automatic scaling of problem +data for the specified problem object. + +The parameter \verb|flags| specifies scaling options used by the +routine. The options can be combined with the bitwise OR operator and +may be the following: + +\verb|GLP_SF_GM | --- perform geometric mean scaling; + +\verb|GLP_SF_EQ | --- perform equilibration scaling; + +\verb|GLP_SF_2N | --- round scale factors to nearest power of two; + +\verb|GLP_SF_SKIP| --- skip scaling, if the problem is well scaled. + +The parameter \verb|flags| may be also specified as \verb|GLP_SF_AUTO|, +in which case the routine chooses the scaling options automatically. + +\vspace*{-6pt} + +\subsection{glp\_unscale\_prob --- unscale problem data} + +\vspace*{-4pt} + +\synopsis + +\begin{verbatim} + void glp_unscale_prob(glp_prob *P); +\end{verbatim} + +The routine \verb|glp_unscale_prob| performs unscaling of problem data +for the specified problem object. + +``Unscaling'' means replacing the current scaling matrices $R$ and $S$ +by unity matrices that cancels the scaling effect. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{LP basis constructing routines} + +\subsection{Background} + +To start the search the simplex method needs a valid initial basis. +In GLPK the basis is completely defined by a set of {\it statuses} +assigned to {\it all} (auxiliary and structural) variables, where the +status may be one of the following: + +\verb|GLP_BS| --- basic variable; + +\verb|GLP_NL| --- non-basic variable having active lower bound; + +\verb|GLP_NU| --- non-basic variable having active upper bound; + +\verb|GLP_NF| --- non-basic free variable; + +\verb|GLP_NS| --- non-basic fixed variable. + +The basis is {\it valid}, if the basis matrix, which is a matrix built +of columns of the augmented constraint matrix $(I\:|-A)$ corresponding +to basic variables, is non-singular. This, in particular, means that +the number of basic variables must be the same as the number of rows in +the problem object. (For more details see Section \ref{lpbasis}, page +\pageref{lpbasis}.) + +Any initial basis may be constructed (or restored) with the API +routines \verb|glp_set_row_stat| and \verb|glp_set_col_stat| by +assigning appropriate statuses to auxiliary and structural variables. +Another way to construct an initial basis is to use API routines like +\verb|glp_adv_basis|, which implement so called +{\it crashing}.\footnote{This term is from early linear programming +systems and means a heuristic to construct a valid initial basis.} Note +that on normal exit the simplex solver remains the basis valid, so in +case of re-optimization there is no need to construct an initial basis +from scratch. + +\subsection{glp\_set\_row\_stat --- set (change) row status} + +\synopsis + +\begin{verbatim} + void glp_set_row_stat(glp_prob *P, int i, int stat); +\end{verbatim} + +\description + +The routine \verb|glp_set_row_stat| sets (changes) the current status +of \verb|i|-th row (auxiliary variable) as specified by the parameter +\verb|stat|: + +\verb|GLP_BS| --- make the row basic (make the constraint inactive); + +\verb|GLP_NL| --- make the row non-basic (make the constraint active); + +\verb|GLP_NU| --- make the row non-basic and set it to the upper bound; +if the row is not double-bounded, this status is equivalent to +\verb|GLP_NL| (only in case of this routine); + +\verb|GLP_NF| --- the same as \verb|GLP_NL| (only in case of this +routine); + +\verb|GLP_NS| --- the same as \verb|GLP_NL| (only in case of this +routine). + +\newpage + +\subsection{glp\_set\_col\_stat --- set (change) column status} + +\synopsis + +\begin{verbatim} + void glp_set_col_stat(glp_prob *P, int j, int stat); +\end{verbatim} + +\description + +The routine \verb|glp_set_col_stat sets| (changes) the current status +of \verb|j|-th column (structural variable) as specified by the +parameter \verb|stat|: + +\verb|GLP_BS| --- make the column basic; + +\verb|GLP_NL| --- make the column non-basic; + +\verb|GLP_NU| --- make the column non-basic and set it to the upper +bound; if the column is not double-bounded, this status is equivalent +to \verb|GLP_NL| (only in case of this routine); + +\verb|GLP_NF| --- the same as \verb|GLP_NL| (only in case of this +routine); + +\verb|GLP_NS| --- the same as \verb|GLP_NL| (only in case of this +routine). + +\subsection{glp\_std\_basis --- construct standard initial LP basis} + +\synopsis + +\begin{verbatim} + void glp_std_basis(glp_prob *P); +\end{verbatim} + +\description + +The routine \verb|glp_std_basis| constructs the ``standard'' (trivial) +initial LP basis for the specified problem object. + +In the ``standard'' LP basis all auxiliary variables (rows) are basic, +and all structural variables (columns) are non-basic (so the +corresponding basis matrix is unity). + +\subsection{glp\_adv\_basis --- construct advanced initial LP basis} + +\synopsis + +\begin{verbatim} + void glp_adv_basis(glp_prob *P, int flags); +\end{verbatim} + +\description + +The routine \verb|glp_adv_basis| constructs an advanced initial LP +basis for the specified problem object. + +The parameter \verb|flags| is reserved for use in the future and must +be specified as zero. + +In order to construct the advanced initial LP basis the routine does +the following: + +1) includes in the basis all non-fixed auxiliary variables; + +2) includes in the basis as many non-fixed structural variables as +possible keeping the triangular form of the basis matrix; + +3) includes in the basis appropriate (fixed) auxiliary variables to +complete the basis. + +As a result the initial LP basis has as few fixed variables as possible +and the corresponding basis matrix is triangular. + +\subsection{glp\_cpx\_basis --- construct Bixby's initial LP basis} + +\synopsis + +\begin{verbatim} + void glp_cpx_basis(glp_prob *P); +\end{verbatim} + +\description + +The routine \verb|glp_cpx_basis| constructs an initial basis for the +specified problem object with the algorithm proposed by +R.~Bixby.\footnote{Robert E. Bixby, ``Implementing the Simplex Method: +The Initial Basis.'' ORSA Journal on Computing, Vol. 4, No. 3, 1992, +pp. 267-84.} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Simplex method routines} + +The {\it simplex method} is a well known efficient numerical procedure +to solve LP problems. + +On each iteration the simplex method transforms the original system of +equaility constraints (1.2) resolving them through different sets of +variables to an equivalent system called {\it the simplex table} (or +sometimes {\it the simplex tableau}), which has the following form: +$$ +\begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}r} +z&=&d_1(x_N)_1&+&d_2(x_N)_2&+ \dots +&d_n(x_N)_n \\ +(x_B)_1&=&\xi_{11}(x_N)_1& +& \xi_{12}(x_N)_2& + \dots +& + \xi_{1n}(x_N)_n \\ +(x_B)_2&=& \xi_{21}(x_N)_1& +& \xi_{22}(x_N)_2& + \dots +& + \xi_{2n}(x_N)_n \\ +\multicolumn{7}{c} +{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .} \\ +(x_B)_m&=&\xi_{m1}(x_N)_1& +& \xi_{m2}(x_N)_2& + \dots +& + \xi_{mn}(x_N)_n \\ +\end{array} \eqno (2.3) +$$ +where: $(x_B)_1, (x_B)_2, \dots, (x_B)_m$ are basic variables; +$(x_N)_1, (x_N)_2, \dots, (x_N)_n$ are non-basic variables; +$d_1, d_2, \dots, d_n$ are reduced costs; +$\xi_{11}, \xi_{12}, \dots, \xi_{mn}$ are coefficients of the +simplex table. (May note that the original LP problem (1.1)---(1.3) +also has the form of a simplex table, where all equalities are resolved +through auxiliary variables.) + +From the linear programming theory it is known that if an optimal +solution of the LP problem (1.1)---(1.3) exists, it can always be +written in the form (2.3), where non-basic variables are set on their +bounds while values of the objective function and basic variables are +determined by the corresponding equalities of the simplex table. + +A set of values of all basic and non-basic variables determined by the +simplex table is called {\it basic solution}. If all basic variables +are within their bounds, the basic solution is called {\it (primal) +feasible}, otherwise it is called {\it (primal) infeasible}. A feasible +basic solution, which provides a smallest (in case of minimization) or +a largest (in case of maximization) value of the objective function is +called {\it optimal}. Therefore, for solving LP problem the simplex +method tries to find its optimal basic solution. + +Primal feasibility of some basic solution may be stated by simple +checking if all basic variables are within their bounds. Basic solution +is optimal if additionally the following optimality conditions are +satisfied for all non-basic variables: +\begin{center} +\begin{tabular}{lcc} +Status of $(x_N)_j$ & Minimization & Maximization \\ +\hline +$(x_N)_j$ is free & $d_j = 0$ & $d_j = 0$ \\ +$(x_N)_j$ is on its lower bound & $d_j \geq 0$ & $d_j \leq 0$ \\ +$(x_N)_j$ is on its upper bound & $d_j \leq 0$ & $d_j \geq 0$ \\ +\end{tabular} +\end{center} +In other words, basic solution is optimal if there is no non-basic +variable, which changing in the feasible direction (i.e. increasing if +it is free or on its lower bound, or decreasing if it is free or on its +upper bound) can improve (i.e. decrease in case of minimization or +increase in case of maximization) the objective function. + +If all non-basic variables satisfy to the optimality conditions shown +above (independently on whether basic variables are within their bounds +or not), the basic solution is called {\it dual feasible}, otherwise it +is called {\it dual infeasible}. + +It may happen that some LP problem has no primal feasible solution due +to incorrect\linebreak formulation --- this means that its constraints +conflict with each other. It also may happen that some LP problem has +unbounded solution again due to incorrect formulation --- this means +that some non-basic variable can improve the objective function, i.e. +the optimality conditions are violated, and at the same time this +variable can infinitely change in the feasible direction meeting +no resistance from basic variables. (May note that in the latter case +the LP problem has no dual feasible solution.) + +\subsection{glp\_simplex --- solve LP problem with the primal or dual +simplex method} + +\synopsis + +\begin{verbatim} + int glp_simplex(glp_prob *P, const glp_smcp *parm); +\end{verbatim} + +\description + +The routine \verb|glp_simplex| is a driver to the LP solver based on +the simplex method. This routine retrieves problem data from the +specified problem object, calls the solver to solve the problem +instance, and stores results of computations back into the problem +object. + +The simplex solver has a set of control parameters. Values of the +control parameters can be passed in the structure \verb|glp_smcp|, +which the parameter \verb|parm| points to. For detailed description of +this structure see paragraph ``Control parameters'' below. +Before specifying some control parameters the application program +should initialize the structure \verb|glp_smcp| by default values of +all control parameters using the routine \verb|glp_init_smcp| (see the +next subsection). This is needed for backward compatibility, because in +the future there may appear new members in the structure +\verb|glp_smcp|. + +The parameter \verb|parm| can be specified as \verb|NULL|, in which +case the solver uses default settings. + +\returns + +\begin{retlist} +0 & The LP problem instance has been successfully solved. (This code +does {\it not} necessarily mean that the solver has found optimal +solution. It only means that the solution process was successful.) \\ + +\verb|GLP_EBADB| & Unable to start the search, because the initial +basis specified in the problem object is invalid---the number of basic +(auxiliary and structural) variables is not the same as the number of +rows in the problem object.\\ + +\verb|GLP_ESING| & Unable to start the search, because the basis matrix +corresponding to the initial basis is singular within the working +precision.\\ + +\verb|GLP_ECOND| & Unable to start the search, because the basis matrix +corresponding to the initial basis is ill-conditioned, i.e. its +condition number is too large.\\ + +\verb|GLP_EBOUND| & Unable to start the search, because some +double-bounded (auxiliary or structural) variables have incorrect +bounds.\\ + +\verb|GLP_EFAIL| & The search was prematurely terminated due to the +solver failure.\\ + +\verb|GLP_EOBJLL| & The search was prematurely terminated, because the +objective function being maximized has reached its lower limit and +continues decreasing (the dual simplex only).\\ + +\verb|GLP_EOBJUL| & The search was prematurely terminated, because the +objective function being minimized has reached its upper limit and +continues increasing (the dual simplex only).\\ + +\verb|GLP_EITLIM| & The search was prematurely terminated, because the +simplex iteration limit has been exceeded.\\ + +\verb|GLP_ETMLIM| & The search was prematurely terminated, because the +time limit has been exceeded.\\ +\end{retlist} + +\begin{retlist} +\verb|GLP_ENOPFS| & The LP problem instance has no primal feasible +solution (only if the LP presolver is used).\\ + +\verb|GLP_ENODFS| & The LP problem instance has no dual feasible +solution (only if the LP presolver is used).\\ +\end{retlist} + +\para{Built-in LP presolver} + +The simplex solver has {\it built-in LP presolver}. It is a subprogram +that transforms the original LP problem specified in the problem object +to an equivalent LP problem, which may be easier for solving with the +simplex method than the original one. This is attained mainly due to +reducing the problem size and improving its numeric properties (for +example, by removing some inactive constraints or by fixing some +non-basic variables). Once the transformed LP problem has been solved, +the presolver transforms its basic solution back to the corresponding +basic solution of the original problem. + +Presolving is an optional feature of the routine \verb|glp_simplex|, +and by default it is disabled. In order to enable the LP presolver the +control parameter \verb|presolve| should be set to \verb|GLP_ON| (see +paragraph ``Control parameters'' below). Presolving may be used when +the problem instance is solved for the first time. However, on +performing re-optimization the presolver should be disabled. + +The presolving procedure is transparent to the API user in the sense +that all necessary processing is performed internally, and a basic +solution of the original problem recovered by the presolver is the same +as if it were computed directly, i.e. without presolving. + +Note that the presolver is able to recover only optimal solutions. If +a computed solution is infeasible or non-optimal, the corresponding +solution of the original problem cannot be recovered and therefore +remains undefined. If you need to know a basic solution even if it is +infeasible or non-optimal, the presolver should be disabled. + +\para{Terminal output} + +Solving large problem instances may take a long time, so the solver +reports some information about the current basic solution, which is +sent to the terminal. This information has the following format: + +\begin{verbatim} + nnn: obj = xxx infeas = yyy (num) cnt +\end{verbatim} + +\noindent +where: `\verb|nnn|' is the iteration number, `\verb|xxx|' is the +current value of the objective function (it is unscaled and has correct +sign); `\verb|yyy|' is the current sum of primal or dual +infeasibilities (it is scaled and therefore may be used only for visual +estimating), `\verb|num|' is the current number of primal or dual +infeasibilities (phase I) or non-optimalities (phase II), `\verb|cnt|' +is the number of basis factorizations since the last terminal output. + +The symbol preceding the iteration number indicates which phase of the +simplex method is in effect: + +{\it Blank} means that the solver is searching for primal feasible +solution using the primal simplex or for dual feasible solution using +the dual simplex; + +{\it Asterisk} (\verb|*|) means that the solver is searching for +optimal solution using the primal simplex; + +{\it Hash} (\verb|#|) means that the solver is searching for optimal +solution using the dual simplex. + +\newpage + +\para{Control parameters} + +This paragraph describes all control parameters currently used in the +simplex solver. Symbolic names of control parameters are names of +corresponding members in the structure \verb|glp_smcp|. + +\bigskip + +{\tt int msg\_lev} (default: {\tt GLP\_MSG\_ALL}) + +Message level for terminal output: + +\verb|GLP_MSG_OFF| --- no output; + +\verb|GLP_MSG_ERR| --- error and warning messages only; + +\verb|GLP_MSG_ON | --- normal output; + +\verb|GLP_MSG_ALL| --- full output (including informational messages). + +\bigskip + +{\tt int meth} (default: {\tt GLP\_PRIMAL}) + +Simplex method option: + +\verb|GLP_PRIMAL| --- use two-phase primal simplex; + +\verb|GLP_DUAL | --- use two-phase dual simplex; + +\verb|GLP_DUALP | --- use two-phase dual simplex, and if it fails, +switch to the primal simplex. + +\bigskip + +{\tt int pricing} (default: {\tt GLP\_PT\_PSE}) + +Pricing technique: + +\verb|GLP_PT_STD| --- standard (``textbook''); + +\verb|GLP_PT_PSE| --- projected steepest edge. + +\bigskip + +{\tt int r\_test} (default: {\tt GLP\_RT\_HAR}) + +Ratio test technique: + +\verb|GLP_RT_STD| --- standard (``textbook''); + +\verb|GLP_RT_HAR| --- Harris' two-pass ratio test. + +\bigskip + +{\tt double tol\_bnd} (default: {\tt 1e-7}) + +Tolerance used to check if the basic solution is primal feasible. +(Do not change this parameter without detailed understanding its +purpose.) + +%\newpage +\bigskip + +{\tt double tol\_dj} (default: {\tt 1e-7}) + +Tolerance used to check if the basic solution is dual feasible. +(Do not change this parameter without detailed understanding its +purpose.) + +\bigskip + +{\tt double tol\_piv} (default: {\tt 1e-9}) + +Tolerance used to choose eligble pivotal elements of the simplex table. +(Do not change this parameter without detailed understanding its +purpose.) + +%\bigskip +\newpage + +{\tt double obj\_ll} (default: {\tt -DBL\_MAX}) + +Lower limit of the objective function. If the objective function +reaches this limit and continues decreasing, the solver terminates the +search. (Used in the dual simplex only.) + +\bigskip + +{\tt double obj\_ul} (default: {\tt +DBL\_MAX}) + +Upper limit of the objective function. If the objective function +reaches this limit and continues increasing, the solver terminates the +search. (Used in the dual simplex only.) + +\bigskip + +{\tt int it\_lim} (default: {\tt INT\_MAX}) + +Simplex iteration limit. + +\bigskip + +{\tt int tm\_lim} (default: {\tt INT\_MAX}) + +Searching time limit, in milliseconds. + +\bigskip + +{\tt int out\_frq} (default: {\tt 500}) + +Output frequency, in iterations. This parameter specifies how +frequently the solver sends information about the solution process to +the terminal. + +\bigskip + +{\tt int out\_dly} (default: {\tt 0}) + +Output delay, in milliseconds. This parameter specifies how long the +solver should delay sending information about the solution process to +the terminal. + +\bigskip + +{\tt int presolve} (default: {\tt GLP\_OFF}) + +LP presolver option: + +\verb|GLP_ON | --- enable using the LP presolver; + +\verb|GLP_OFF| --- disable using the LP presolver. + +\newpage + +\para{Example 1} + +The following example main program reads LP problem instance in fixed +MPS format from file \verb|25fv47.mps|,\footnote{This instance in fixed +MPS format can be found in the Netlib LP collection; see +{\tt ftp://ftp.netlib.org/lp/data/}.} constructs an advanced initial +basis, solves the instance with the primal simplex method (by default), +and writes the solution to file \verb|25fv47.txt|. + +\begin{footnotesize} +\begin{verbatim} +/* spxsamp1.c */ + +#include <stdio.h> +#include <stdlib.h> +#include <glpk.h> + +int main(void) +{ glp_prob *P; + P = glp_create_prob(); + glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps"); + glp_adv_basis(P, 0); + glp_simplex(P, NULL); + glp_print_sol(P, "25fv47.txt"); + glp_delete_prob(P); + return 0; +} + +/* eof */ +\end{verbatim} +\end{footnotesize} + +Below here is shown the terminal output from this example program. + +\begin{footnotesize} +\begin{verbatim} +Reading problem data from '25fv47.mps'... +Problem: 25FV47 +Objective: R0000 +822 rows, 1571 columns, 11127 non-zeros +6919 records were read +One free row was removed +Constructing initial basis... +Size of triangular part is 812 +GLPK Simplex Optimizer, v4.57 +821 rows, 1571 columns, 10400 non-zeros + 0: obj = 7.131703290e+03 inf = 2.145e+05 (204) + 500: obj = 1.886711682e+04 inf = 8.273e+02 (36) 4 + 741: obj = 1.846047936e+04 inf = 5.575e-14 (0) 2 +* 1000: obj = 9.220063473e+03 inf = 2.423e-14 (432) 2 +* 1500: obj = 6.187659664e+03 inf = 1.019e-13 (368) 4 +* 2000: obj = 5.503442062e+03 inf = 0.000e+00 (33) 5 +* 2052: obj = 5.501845888e+03 inf = 0.000e+00 (0) +OPTIMAL LP SOLUTION FOUND +Writing basic solution to '25fv47.txt'... +\end{verbatim} +\end{footnotesize} + +\newpage + +\para{Example 2} + +The following example main program solves the same LP problem instance +as in Example 1 above, however, it uses the dual simplex method, which +starts from the standard initial basis. + +\begin{footnotesize} +\begin{verbatim} +/* spxsamp2.c */ + +#include <stdio.h> +#include <stdlib.h> +#include <glpk.h> + +int main(void) +{ glp_prob *P; + glp_smcp parm; + P = glp_create_prob(); + glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps"); + glp_init_smcp(&parm); + parm.meth = GLP_DUAL; + glp_simplex(P, &parm); + glp_print_sol(P, "25fv47.txt"); + glp_delete_prob(P); + return 0; +} + +/* eof */ +\end{verbatim} +\end{footnotesize} + +Below here is shown the terminal output from this example program. + +\begin{footnotesize} +\begin{verbatim} +Reading problem data from '25fv47.mps'... +Problem: 25FV47 +Objective: R0000 +822 rows, 1571 columns, 11127 non-zeros +6919 records were read +One free row was removed +GLPK Simplex Optimizer, v4.57 +821 rows, 1571 columns, 10400 non-zeros + 0: inf = 1.223e+02 (41) + 258: inf = 3.091e-16 (0) 2 +# 500: obj = -5.071287080e+03 inf = 2.947e-15 (292) 2 +# 1000: obj = -1.352843873e+03 inf = 8.452e-15 (302) 5 +# 1500: obj = 7.985859737e+02 inf = 1.127e-14 (263) 5 +# 2000: obj = 3.059023029e+03 inf = 6.290e-11 (197) 4 +# 2500: obj = 5.354770966e+03 inf = 7.172e-13 (130) 5 +# 2673: obj = 5.501845888e+03 inf = 3.802e-16 (0) 2 +OPTIMAL LP SOLUTION FOUND +Writing basic solution to '25fv47.txt'... +\end{verbatim} +\end{footnotesize} + +\newpage + +\subsection{glp\_exact --- solve LP problem in exact arithmetic} + +\synopsis + +\begin{verbatim} + int glp_exact(glp_prob *P, const glp_smcp *parm); +\end{verbatim} + +\description + +The routine \verb|glp_exact| is a tentative implementation of the +primal two-phase simplex method based on exact (rational) arithmetic. +It is similar to the routine \verb|glp_simplex|, however, for all +internal computations it uses arithmetic of rational numbers, which is +exact in mathematical sense, i.e. free of round-off errors unlike +floating-point arithmetic. + +Note that the routine \verb|glp_exact| uses only three control +parameters passed in the structure \verb|glp_smcp|, namely, +\verb|msg_lev|, \verb|it_lim|, and \verb|tm_lim|. + +\returns + +\begin{retlist} +0 & The LP problem instance has been successfully solved. (This code +does {\it not} necessarily mean that the solver has found optimal +solution. It only means that the solution process was successful.) \\ + +\verb|GLP_EBADB| & Unable to start the search, because the initial basis +specified in the problem object is invalid---the number of basic +(auxiliary and structural) variables is not the same as the number of +rows in the problem object.\\ + +\verb|GLP_ESING| & Unable to start the search, because the basis matrix +corresponding to the initial basis is exactly singular.\\ + +\verb|GLP_EBOUND| & Unable to start the search, because some +double-bounded (auxiliary or structural) variables have incorrect +bounds.\\ + +\verb|GLP_EFAIL| & The problem instance has no rows/columns.\\ + +\verb|GLP_EITLIM| & The search was prematurely terminated, because the +simplex iteration limit has been exceeded.\\ + +\verb|GLP_ETMLIM| & The search was prematurely terminated, because the +time limit has been exceeded.\\ +\end{retlist} + +\para{Note} + +Computations in exact arithmetic are very time-consuming, so solving +LP problem with the routine \verb|glp_exact| from the very beginning is +not a good idea. It is much better at first to find an optimal basis +with the routine \verb|glp_simplex| and only then to call +\verb|glp_exact|, in which case only a few simplex iterations need to +be performed in exact arithmetic. + +\newpage + +\subsection{glp\_init\_smcp --- initialize simplex solver control +parameters} + +\synopsis + +\begin{verbatim} + int glp_init_smcp(glp_smcp *parm); +\end{verbatim} + +\description + +The routine \verb|glp_init_smcp| initializes control parameters, which +are used by the simplex solver, with default values. + +Default values of the control parameters are stored in +a \verb|glp_smcp| structure, which the parameter \verb|parm| points to. + +\subsection{glp\_get\_status --- determine generic status of basic +solution} + +\synopsis + +\begin{verbatim} + int glp_get_status(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_status| reports the generic status of the +current basic solution for the specified problem object as follows: + +\verb|GLP_OPT | --- solution is optimal; + +\verb|GLP_FEAS | --- solution is feasible; + +\verb|GLP_INFEAS| --- solution is infeasible; + +\verb|GLP_NOFEAS| --- problem has no feasible solution; + +\verb|GLP_UNBND | --- problem has unbounded solution; + +\verb|GLP_UNDEF | --- solution is undefined. + +More detailed information about the status of basic solution can be +retrieved with the routines \verb|glp_get_prim_stat| and +\verb|glp_get_dual_stat|. + +\subsection{glp\_get\_prim\_stat --- retrieve status of primal basic +solution} + +\synopsis + +\begin{verbatim} + int glp_get_prim_stat(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_prim_stat| reports the status of the primal +basic solution for the specified problem object as follows: + +\verb|GLP_UNDEF | --- primal solution is undefined; + +\verb|GLP_FEAS | --- primal solution is feasible; + +\verb|GLP_INFEAS| --- primal solution is infeasible; + +\verb|GLP_NOFEAS| --- no primal feasible solution exists. + +\subsection{glp\_get\_dual\_stat --- retrieve status of dual basic +solution} + +\synopsis + +\begin{verbatim} + int glp_get_dual_stat(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_dual_stat| reports the status of the dual +basic solution for the specified problem object as follows: + +\verb|GLP_UNDEF | --- dual solution is undefined; + +\verb|GLP_FEAS | --- dual solution is feasible; + +\verb|GLP_INFEAS| --- dual solution is infeasible; + +\verb|GLP_NOFEAS| --- no dual feasible solution exists. + +\subsection{glp\_get\_obj\_val --- retrieve objective value} + +\synopsis + +\begin{verbatim} + double glp_get_obj_val(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_obj_val| returns current value of the +objective function. + +\subsection{glp\_get\_row\_stat --- retrieve row status} + +\synopsis + +\begin{verbatim} + int glp_get_row_stat(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_get_row_stat| returns current status assigned to +the auxiliary variable associated with \verb|i|-th row as follows: + +\verb|GLP_BS| --- basic variable; + +\verb|GLP_NL| --- non-basic variable on its lower bound; + +\verb|GLP_NU| --- non-basic variable on its upper bound; + +\verb|GLP_NF| --- non-basic free (unbounded) variable; + +\verb|GLP_NS| --- non-basic fixed variable. + +%\newpage + +\subsection{glp\_get\_row\_prim --- retrieve row primal value} + +\synopsis + +\begin{verbatim} + double glp_get_row_prim(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_get_row_prim| returns primal value of the +auxiliary variable associated with \verb|i|-th row. + +\subsection{glp\_get\_row\_dual --- retrieve row dual value} + +\synopsis + +\begin{verbatim} + double glp_get_row_dual(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_get_row_dual| returns dual value (i.e. reduced +cost) of the auxiliary variable associated with \verb|i|-th row. + +\subsection{glp\_get\_col\_stat --- retrieve column status} + +\synopsis + +\begin{verbatim} + int glp_get_col_stat(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_get_col_stat| returns current status assigned to +the structural variable associated with \verb|j|-th column as follows: + +\verb|GLP_BS| --- basic variable; + +\verb|GLP_NL| --- non-basic variable on its lower bound; + +\verb|GLP_NU| --- non-basic variable on its upper bound; + +\verb|GLP_NF| --- non-basic free (unbounded) variable; + +\verb|GLP_NS| --- non-basic fixed variable. + +\subsection{glp\_get\_col\_prim --- retrieve column primal value} + +\synopsis + +\begin{verbatim} + double glp_get_col_prim(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_get_col_prim| returns primal value of the +structural variable associated with \verb|j|-th column. + +%\newpage + +\subsection{glp\_get\_col\_dual --- retrieve column dual value} + +\synopsis + +\begin{verbatim} + double glp_get_col_dual(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_get_col_dual| returns dual value (i.e. reduced +cost) of the structural variable associated with \verb|j|-th column. + +\newpage + +\subsection{glp\_get\_unbnd\_ray --- determine variable causing +unboundedness} + +\synopsis + +\begin{verbatim} + int glp_get_unbnd_ray(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_unbnd_ray| returns the number $k$ of +a variable, which causes primal or dual unboundedness. +If $1\leq k\leq m$, it is $k$-th auxiliary variable, and if +$m+1\leq k\leq m+n$, it is $(k-m)$-th structural variable, where $m$ is +the number of rows, $n$ is the number of columns in the problem object. +If such variable is not defined, the routine returns 0. + +\para{Note} + +If it is not exactly known which version of the simplex solver +detected unboundedness, i.e. whether the unboundedness is primal or +dual, it is sufficient to check the status of the variable +with the routine \verb|glp_get_row_stat| or \verb|glp_get_col_stat|. +If the variable is non-basic, the unboundedness is primal, otherwise, +if the variable is basic, the unboundedness is dual (the latter case +means that the problem has no primal feasible dolution). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Interior-point method routines} + +{\it Interior-point methods} (also known as {\it barrier methods}) are +more modern and powerful numerical methods for large-scale linear +programming. Such methods are especially efficient for very sparse LP +problems and allow solving such problems much faster than the simplex +method. + +In brief, the GLPK interior-point solver works as follows. + +At first, the solver transforms the original LP to a {\it working} LP +in the standard format: + +\medskip + +\noindent +\hspace{.5in} minimize +$$z = c_1x_{m+1} + c_2x_{m+2} + \dots + c_nx_{m+n} + c_0 \eqno (2.4)$$ +\hspace{.5in} subject to linear constraints +$$ +\begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}l} +a_{11}x_{m+1}&+&a_{12}x_{m+2}&+ \dots +&a_{1n}x_{m+n}&=&b_1 \\ +a_{21}x_{m+1}&+&a_{22}x_{m+2}&+ \dots +&a_{2n}x_{m+n}&=&b_2 \\ +\multicolumn{7}{c} +{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .} \\ +a_{m1}x_{m+1}&+&a_{m2}x_{m+2}&+ \dots +&a_{mn}x_{m+n}&=&b_m \\ +\end{array} \eqno (2.5) +$$ +\hspace{.5in} and non-negative variables +$$x_1\geq 0,\ \ x_2\geq 0,\ \ \dots,\ \ x_n\geq 0 \eqno(2.6)$$ +where: $z$ is the objective function; $x_1$, \dots, $x_n$ are variables; +$c_1$, \dots, $c_n$ are objective coefficients; $c_0$ is a constant term +of the objective function; $a_{11}$, \dots, $a_{mn}$ are constraint +coefficients; $b_1$, \dots, $b_m$ are right-hand sides. + +Using vector and matrix notations the working LP (2.4)---(2.6) can be +written as follows: +$$z=c^Tx+c_0\ \rightarrow\ \min,\eqno(2.7)$$ +$$Ax=b,\eqno(2.8)$$ +$$x\geq 0,\eqno(2.9)$$ +where: $x=(x_j)$ is $n$-vector of variables, $c=(c_j)$ is $n$-vector of +objective coefficients, $A=(a_{ij})$ is $m\times n$-matrix of +constraint coefficients, and $b=(b_i)$ is $m$-vector of right-hand +sides. + +Karush--Kuhn--Tucker optimality conditions for LP (2.7)---(2.9) are the +following: +$$Ax=b,\eqno(2.10)$$ +$$A^T\pi+\lambda=c,\eqno(2.11)$$ +$$\lambda^Tx=0,\eqno(2.12)$$ +$$x\geq 0,\ \ \lambda\geq 0,\eqno(2.13)$$ +where: +$\pi$ is $m$-vector of Lagrange multipliers (dual variables) for +equality constraints (2.8),\linebreak $\lambda$ is $n$-vector of +Lagrange multipliers (dual variables) for non-negativity constraints +(2.9),\linebreak (2.10) is the primal feasibility condition, (2.11) is +the dual feasibility condition, (2.12) is the primal-dual +complementarity condition, and (2.13) is the non-negativity conditions. + +The main idea of the primal-dual interior-point method is based on +finding a point in the primal-dual space (i.e. in the space of all +primal and dual variables $x$, $\pi$, and $\lambda$), which satisfies +to all optimality conditions (2.10)---(2.13). Obviously, $x$-component +of such point then provides an optimal solution to the working LP +(2.7)---(2.9). + +To find the optimal point $(x^*,\pi^*,\lambda^*)$ the interior-point +method attempts to solve the system of equations (2.10)---(2.12), which +is closed in the sense that the number of variables $x_j$, $\pi_i$, and +$\lambda_j$ and the number equations are the same and equal to $m+2n$. +Due to condition (2.12) this system of equations is non-linear, so it +can be solved with a version of {\it Newton's method} provided with +additional rules to keep the current point within the positive orthant +as required by the non-negativity conditions (2.13). + +Finally, once the optimal point $(x^*,\pi^*,\lambda^*)$ has been found, +the solver performs inverse transformations to recover corresponding +solution to the original LP passed to the solver from the application +program. + +\subsection{glp\_interior --- solve LP problem with the interior-point +method} + +\synopsis + +\begin{verbatim} + int glp_interior(glp_prob *P, const glp_iptcp *parm); +\end{verbatim} + +\description + +The routine \verb|glp_interior| is a driver to the LP solver based on +the primal-dual interior-point method. This routine retrieves problem +data from the specified problem object, calls the solver to solve the +problem instance, and stores results of computations back into the +problem object. + +The interior-point solver has a set of control parameters. Values of +the control parameters can be passed in the structure \verb|glp_iptcp|, +which the parameter \verb|parm| points to. For detailed description of +this structure see paragraph ``Control parameters'' below. Before +specifying some control parameters the application program should +initialize the structure \verb|glp_iptcp| by default values of all +control parameters using the routine \verb|glp_init_iptcp| (see the +next subsection). This is needed for backward compatibility, because in +the future there may appear new members in the structure +\verb|glp_iptcp|. + +The parameter \verb|parm| can be specified as \verb|NULL|, in which +case the solver uses default settings. + +\returns + +\begin{retlist} +0 & The LP problem instance has been successfully solved. (This code +does {\it not} necessarily mean that the solver has found optimal +solution. It only means that the solution process was successful.) \\ + +\verb|GLP_EFAIL| & The problem has no rows/columns.\\ + +\verb|GLP_ENOCVG| & Very slow convergence or divergence.\\ + +\verb|GLP_EITLIM| & Iteration limit exceeded.\\ + +\verb|GLP_EINSTAB| & Numerical instability on solving Newtonian +system.\\ +\end{retlist} + +\newpage + +\para{Comments} + +The routine \verb|glp_interior| implements an easy version of +the primal-dual interior-point method based on Mehrotra's +technique.\footnote{S. Mehrotra. On the implementation of a primal-dual +interior point method. SIAM J. on Optim., 2(4), pp. 575-601, 1992.} + +Note that currently the GLPK interior-point solver does not include +many important features, in particular: + +%\vspace*{-8pt} + +%\begin{itemize} +\Item{---}it is not able to process dense columns. Thus, if the +constraint matrix of the LP problem has dense columns, the solving +process may be inefficient; + +\Item{---}it has no features against numerical instability. For some LP +problems premature termination may happen if the matrix $ADA^T$ becomes +singular or ill-conditioned; + +\Item{---}it is not able to identify the optimal basis, which +corresponds to the interior-point solution found. +%\end{itemize} + +%\vspace*{-8pt} + +\para{Terminal output} + +Solving large LP problems may take a long time, so the solver reports +some information about every interior-point iteration,\footnote{Unlike +the simplex method the interior point method usually needs 30---50 +iterations (independently on the problem size) in order to find an +optimal solution.} which is sent to the terminal. This information has +the following format: + +\begin{verbatim} +nnn: obj = fff; rpi = ppp; rdi = ddd; gap = ggg +\end{verbatim} + +\noindent where: \verb|nnn| is iteration number, \verb|fff| is the +current value of the objective function (in the case of maximization it +has wrong sign), \verb|ppp| is the current relative primal +infeasibility (cf. (2.10)): +$$\frac{\|Ax^{(k)}-b\|}{1+\|b\|},\eqno(2.14)$$ +\verb|ddd| is the current relative dual infeasibility (cf. (2.11)): +$$\frac{\|A^T\pi^{(k)}+\lambda^{(k)}-c\|}{1+\|c\|},\eqno(2.15)$$ +\verb|ggg| is the current primal-dual gap (cf. (2.12)): +$$\frac{|c^Tx^{(k)}-b^T\pi^{(k)}|}{1+|c^Tx^{(k)}|},\eqno(2.16)$$ +and $[x^{(k)},\pi^{(k)},\lambda^{(k)}]$ is the current point on $k$-th +iteration, $k=0,1,2,\dots$\ . Note that all solution components are +internally scaled, so information sent to the terminal is suitable only +for visual inspection. + +\newpage + +\para{Control parameters} + +This paragraph describes all control parameters currently used in the +interior-point solver. Symbolic names of control parameters are names of +corresponding members in the structure \verb|glp_iptcp|. + +\bigskip + +{\tt int msg\_lev} (default: {\tt GLP\_MSG\_ALL}) + +Message level for terminal output: + +\verb|GLP_MSG_OFF|---no output; + +\verb|GLP_MSG_ERR|---error and warning messages only; + +\verb|GLP_MSG_ON |---normal output; + +\verb|GLP_MSG_ALL|---full output (including informational messages). + +\bigskip + +{\tt int ord\_alg} (default: {\tt GLP\_ORD\_AMD}) + +Ordering algorithm used prior to Cholesky factorization: + +\verb|GLP_ORD_NONE |---use natural (original) ordering; + +\verb|GLP_ORD_QMD |---quotient minimum degree (QMD); + +\verb|GLP_ORD_AMD |---approximate minimum degree (AMD); + +\verb|GLP_ORD_SYMAMD|---approximate minimum degree (SYMAMD). + +\bigskip + +\para{Example} + +The following main program reads LP problem instance in fixed MPS +format from file\linebreak \verb|25fv47.mps|,\footnote{This instance in +fixed MPS format can be found in the Netlib LP collection; see +{\tt ftp://ftp.netlib.org/lp/data/}.} solves it with the interior-point +solver, and writes the solution to file \verb|25fv47.txt|. + +\begin{footnotesize} +\begin{verbatim} +/* iptsamp.c */ + +#include <stdio.h> +#include <stdlib.h> +#include <glpk.h> + +int main(void) +{ glp_prob *P; + P = glp_create_prob(); + glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps"); + glp_interior(P, NULL); + glp_print_ipt(P, "25fv47.txt"); + glp_delete_prob(P); + return 0; +} + +/* eof */ +\end{verbatim} +\end{footnotesize} + +\newpage + +Below here is shown the terminal output from this example program. + +\begin{footnotesize} +\begin{verbatim} +Reading problem data from `25fv47.mps'... +Problem: 25FV47 +Objective: R0000 +822 rows, 1571 columns, 11127 non-zeros +6919 records were read +Original LP has 822 row(s), 1571 column(s), and 11127 non-zero(s) +Working LP has 821 row(s), 1876 column(s), and 10705 non-zero(s) +Matrix A has 10705 non-zeros +Matrix S = A*A' has 11895 non-zeros (upper triangle) +Minimal degree ordering... +Computing Cholesky factorization S = L'*L... +Matrix L has 35411 non-zeros +Guessing initial point... +Optimization begins... + 0: obj = 1.823377629e+05; rpi = 1.3e+01; rdi = 1.4e+01; gap = 9.3e-01 + 1: obj = 9.260045192e+04; rpi = 5.3e+00; rdi = 5.6e+00; gap = 6.8e+00 + 2: obj = 3.596999742e+04; rpi = 1.5e+00; rdi = 1.2e+00; gap = 1.8e+01 + 3: obj = 1.989627568e+04; rpi = 4.7e-01; rdi = 3.0e-01; gap = 1.9e+01 + 4: obj = 1.430215557e+04; rpi = 1.1e-01; rdi = 8.6e-02; gap = 1.4e+01 + 5: obj = 1.155716505e+04; rpi = 2.3e-02; rdi = 2.4e-02; gap = 6.8e+00 + 6: obj = 9.660273208e+03; rpi = 6.7e-03; rdi = 4.6e-03; gap = 3.9e+00 + 7: obj = 8.694348283e+03; rpi = 3.7e-03; rdi = 1.7e-03; gap = 2.0e+00 + 8: obj = 8.019543639e+03; rpi = 2.4e-03; rdi = 3.9e-04; gap = 1.0e+00 + 9: obj = 7.122676293e+03; rpi = 1.2e-03; rdi = 1.5e-04; gap = 6.6e-01 + 10: obj = 6.514534518e+03; rpi = 6.1e-04; rdi = 4.3e-05; gap = 4.1e-01 + 11: obj = 6.361572203e+03; rpi = 4.8e-04; rdi = 2.2e-05; gap = 3.0e-01 + 12: obj = 6.203355508e+03; rpi = 3.2e-04; rdi = 1.7e-05; gap = 2.6e-01 + 13: obj = 6.032943411e+03; rpi = 2.0e-04; rdi = 9.3e-06; gap = 2.1e-01 + 14: obj = 5.796553021e+03; rpi = 9.8e-05; rdi = 3.2e-06; gap = 1.0e-01 + 15: obj = 5.667032431e+03; rpi = 4.4e-05; rdi = 1.1e-06; gap = 5.6e-02 + 16: obj = 5.613911867e+03; rpi = 2.5e-05; rdi = 4.1e-07; gap = 3.5e-02 + 17: obj = 5.560572626e+03; rpi = 9.9e-06; rdi = 2.3e-07; gap = 2.1e-02 + 18: obj = 5.537276001e+03; rpi = 5.5e-06; rdi = 8.4e-08; gap = 1.1e-02 + 19: obj = 5.522746942e+03; rpi = 2.2e-06; rdi = 4.0e-08; gap = 6.7e-03 + 20: obj = 5.509956679e+03; rpi = 7.5e-07; rdi = 1.8e-08; gap = 2.9e-03 + 21: obj = 5.504571733e+03; rpi = 1.6e-07; rdi = 5.8e-09; gap = 1.1e-03 + 22: obj = 5.502576367e+03; rpi = 3.4e-08; rdi = 1.0e-09; gap = 2.5e-04 + 23: obj = 5.502057119e+03; rpi = 8.1e-09; rdi = 3.0e-10; gap = 7.7e-05 + 24: obj = 5.501885996e+03; rpi = 9.4e-10; rdi = 1.2e-10; gap = 2.4e-05 + 25: obj = 5.501852464e+03; rpi = 1.4e-10; rdi = 1.2e-11; gap = 3.0e-06 + 26: obj = 5.501846549e+03; rpi = 1.4e-11; rdi = 1.2e-12; gap = 3.0e-07 + 27: obj = 5.501845954e+03; rpi = 1.4e-12; rdi = 1.2e-13; gap = 3.0e-08 + 28: obj = 5.501845895e+03; rpi = 1.5e-13; rdi = 1.2e-14; gap = 3.0e-09 +OPTIMAL SOLUTION FOUND +Writing interior-point solution to `25fv47.txt'... +\end{verbatim} +\end{footnotesize} + +\newpage + +\subsection{glp\_init\_iptcp --- initialize interior-point solver +control parameters} + +\synopsis + +\begin{verbatim} + int glp_init_iptcp(glp_iptcp *parm); +\end{verbatim} + +\description + +The routine \verb|glp_init_iptcp| initializes control parameters, which +are used by the interior-point solver, with default values. + +Default values of the control parameters are stored in the structure +\verb|glp_iptcp|, which the parameter \verb|parm| points to. + +\subsection{glp\_ipt\_status --- determine solution status} + +\synopsis + +\begin{verbatim} + int glp_ipt_status(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_ipt_status| reports the status of a solution +found by the interior-point solver as follows: + +\verb|GLP_UNDEF | --- interior-point solution is undefined; + +\verb|GLP_OPT | --- interior-point solution is optimal; + +\verb|GLP_INFEAS| --- interior-point solution is infeasible; + +\verb|GLP_NOFEAS| --- no feasible primal-dual solution exists. + +\subsection{glp\_ipt\_obj\_val --- retrieve objective value} + +\synopsis + +\begin{verbatim} + double glp_ipt_obj_val(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_ipt_obj_val| returns value of the objective +function for interior-point solution. + +\subsection{glp\_ipt\_row\_prim --- retrieve row primal value} + +\synopsis + +\begin{verbatim} + double glp_ipt_row_prim(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_ipt_row_prim| returns primal value of the +auxiliary variable associated with \verb|i|-th row. + +\newpage + +\subsection{glp\_ipt\_row\_dual --- retrieve row dual value} + +\synopsis + +\begin{verbatim} + double glp_ipt_row_dual(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_ipt_row_dual| returns dual value (i.e. reduced +cost) of the auxiliary variable associated with \verb|i|-th row. + +\subsection{glp\_ipt\_col\_prim --- retrieve column primal value} + +\synopsis + +\begin{verbatim} + double glp_ipt_col_prim(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_ipt_col_prim| returns primal value of the +structural variable associated with \verb|j|-th column. + +\subsection{glp\_ipt\_col\_dual --- retrieve column dual value} + +\synopsis + +\begin{verbatim} + double glp_ipt_col_dual(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_ipt_col_dual| returns dual value (i.e. reduced +cost) of the structural variable associated with \verb|j|-th column. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Mixed integer programming routines} + +\subsection{glp\_set\_col\_kind --- set (change) column kind} + +\synopsis + +\begin{verbatim} + void glp_set_col_kind(glp_prob *P, int j, int kind); +\end{verbatim} + +\description + +The routine \verb|glp_set_col_kind| sets (changes) the kind of +\verb|j|-th column (structural variable) as specified by the parameter +\verb|kind|: + +\verb|GLP_CV| --- continuous variable; + +\verb|GLP_IV| --- integer variable; + +\verb|GLP_BV| --- binary variable. + +Setting a column to \verb|GLP_BV| has the same effect as if it were +set to \verb|GLP_IV|, its lower bound were set 0, and its upper bound +were set to 1. + +\subsection{glp\_get\_col\_kind --- retrieve column kind} + +\synopsis + +\begin{verbatim} + int glp_get_col_kind(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_get_col_kind| returns the kind of \verb|j|-th +column (structural variable) as follows: + +\verb|GLP_CV| --- continuous variable; + +\verb|GLP_IV| --- integer variable; + +\verb|GLP_BV| --- binary variable. + +\subsection{glp\_get\_num\_int --- retrieve number of integer columns} + +\synopsis + +\begin{verbatim} + int glp_get_num_int(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_num_int| returns the number of columns +(structural variables), which are marked as integer. Note that this +number {\it does} include binary columns. + +\newpage + +\subsection{glp\_get\_num\_bin --- retrieve number of binary columns} + +\synopsis + +\begin{verbatim} + int glp_get_num_bin(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_num_bin| returns the number of columns +(structural variables), which are marked as integer and whose lower +bound is zero and upper bound is one. + +\subsection{glp\_intopt --- solve MIP problem with the branch-and-cut +method} + +\synopsis + +\begin{verbatim} + int glp_intopt(glp_prob *P, const glp_iocp *parm); +\end{verbatim} + +\description + +The routine \verb|glp_intopt| is a driver to the MIP solver based on +the branch-and-cut method, which is a hybrid of branch-and-bound and +cutting plane methods. + +If the presolver is disabled (see paragraph ``Control parameters'' +below), on entry to the routine \verb|glp_intopt| the problem object, +which the parameter \verb|mip| points to, should contain optimal +solution to LP relaxation (it can be obtained, for example, with the +routine \verb|glp_simplex|). Otherwise, if the presolver is enabled, it +is not necessary. + +The MIP solver has a set of control parameters. Values of the control +parameters can be passed in the structure \verb|glp_iocp|, which the +parameter \verb|parm| points to. For detailed description of this +structure see paragraph ``Control parameters'' below. Before specifying +some control parameters the application program should initialize the +structure \verb|glp_iocp| by default values of all control parameters +using the routine \verb|glp_init_iocp| (see the next subsection). This +is needed for backward compatibility, because in the future there may +appear new members in the structure \verb|glp_iocp|. + +The parameter \verb|parm| can be specified as \verb|NULL|, in which case +the solver uses default settings. + +Note that the GLPK branch-and-cut solver is not perfect, so it is +unable to solve hard or very large scale MIP instances for a reasonable +time. + +\returns + +\begin{retlist} +0 & The MIP problem instance has been successfully solved. (This code +does {\it not} necessarily mean that the solver has found optimal +solution. It only means that the solution process was successful.) \\ + +\verb|GLP_EBOUND| & Unable to start the search, because some +double-bounded variables have incorrect bounds or some integer +variables have non-integer (fractional) bounds.\\ + +\verb|GLP_EROOT| & Unable to start the search, because optimal basis +for initial LP relaxation is not provided. (This code may appear only +if the presolver is disabled.)\\ + +\verb|GLP_ENOPFS| & Unable to start the search, because LP relaxation +of the MIP problem instance has no primal feasible solution. (This code +may appear only if the presolver is enabled.)\\ +\end{retlist} + +\newpage + +\begin{retlist} +\verb|GLP_ENODFS| & Unable to start the search, because LP relaxation +of the MIP problem instance has no dual feasible solution. In other +word, this code means that if the LP relaxation has at least one primal +feasible solution, its optimal solution is unbounded, so if the MIP +problem has at least one integer feasible solution, its (integer) +optimal solution is also unbounded. (This code may appear only if the +presolver is enabled.)\\ + +\verb|GLP_EFAIL| & The search was prematurely terminated due to the +solver failure.\\ + +\verb|GLP_EMIPGAP| & The search was prematurely terminated, because the +relative mip gap tolerance has been reached.\\ + +\verb|GLP_ETMLIM| & The search was prematurely terminated, because the +time limit has been exceeded.\\ + +\verb|GLP_ESTOP| & The search was prematurely terminated by application. +(This code may appear only if the advanced solver interface is used.)\\ +\end{retlist} + +\para{Built-in MIP presolver} + +The branch-and-cut solver has {\it built-in MIP presolver}. It is +a subprogram that transforms the original MIP problem specified in the +problem object to an equivalent MIP problem, which may be easier for +solving with the branch-and-cut method than the original one. For +example, the presolver can remove redundant constraints and variables, +whose optimal values are known, perform bound and coefficient reduction, +etc. Once the transformed MIP problem has been solved, the presolver +transforms its solution back to corresponding solution of the original +problem. + +Presolving is an optional feature of the routine \verb|glp_intopt|, and +by default it is disabled. In order to enable the MIP presolver, the +control parameter \verb|presolve| should be set to \verb|GLP_ON| (see +paragraph ``Control parameters'' below). + +\para{Advanced solver interface} + +The routine \verb|glp_intopt| allows the user to control the +branch-and-cut search by passing to the solver a user-defined callback +routine. For more details see Chapter ``Branch-and-Cut API Routines''. + +\para{Terminal output} + +Solving a MIP problem may take a long time, so the solver reports some +information about best known solutions, which is sent to the terminal. +This information has the following format: + +\begin{verbatim} ++nnn: mip = xxx <rho> yyy gap (ppp; qqq) +\end{verbatim} + +\noindent +where: `\verb|nnn|' is the simplex iteration number; `\verb|xxx|' is a +value of the objective function for the best known integer feasible +solution (if no integer feasible solution has been found yet, +`\verb|xxx|' is the text `\verb|not found yet|'); `\verb|rho|' is the +string `\verb|>=|' (in case of minimization) or `\verb|<=|' (in case of +maximization); `\verb|yyy|' is a global bound for exact integer optimum +(i.e. the exact integer optimum is always in the range from `\verb|xxx|' +to `\verb|yyy|'); `\verb|gap|' is the relative mip gap, in percents, +computed as $gap=|xxx-yyy|/(|xxx|+{\tt DBL\_EPSILON})\cdot 100\%$ (if +$gap$ is greater than $999.9\%$, it is not printed); `\verb|ppp|' is the +number of subproblems in the active list, `\verb|qqq|' is the number of +subproblems which have been already fathomed and therefore removed from +the branch-and-bound search tree. + +\newpage + +\subsubsection{Control parameters} + +This paragraph describes all control parameters currently used in the +MIP solver. Symbolic names of control parameters are names of +corresponding members in the structure \verb|glp_iocp|. + +\bigskip\vspace*{-2pt} + +{\tt int msg\_lev} (default: {\tt GLP\_MSG\_ALL}) + +Message level for terminal output: + +\verb|GLP_MSG_OFF| --- no output; + +\verb|GLP_MSG_ERR| --- error and warning messages only; + +\verb|GLP_MSG_ON | --- normal output; + +\verb|GLP_MSG_ALL| --- full output (including informational messages). + +\bigskip\vspace*{-2pt} + +{\tt int br\_tech} (default: {\tt GLP\_BR\_DTH}) + +Branching technique option: + +\verb|GLP_BR_FFV| --- first fractional variable; + +\verb|GLP_BR_LFV| --- last fractional variable; + +\verb|GLP_BR_MFV| --- most fractional variable; + +\verb|GLP_BR_DTH| --- heuristic by Driebeck and Tomlin; + +\verb|GLP_BR_PCH| --- hybrid pseudo-cost heuristic. + +\bigskip\vspace*{-2pt} + +{\tt int bt\_tech} (default: {\tt GLP\_BT\_BLB}) + +Backtracking technique option: + +\verb|GLP_BT_DFS| --- depth first search; + +\verb|GLP_BT_BFS| --- breadth first search; + +\verb|GLP_BT_BLB| --- best local bound; + +\verb|GLP_BT_BPH| --- best projection heuristic. + +\bigskip\vspace*{-2pt} + +{\tt int pp\_tech} (default: {\tt GLP\_PP\_ALL}) + +Preprocessing technique option: + +\verb|GLP_PP_NONE| --- disable preprocessing; + +\verb|GLP_PP_ROOT| --- perform preprocessing only on the root level; + +\verb|GLP_PP_ALL | --- perform preprocessing on all levels. + +\bigskip\vspace*{-2pt} + +{\tt int sr\_heur} (default: {\tt GLP\_ON}) + +Simple rounding heuristic option: + +\verb|GLP_ON | --- enable applying the simple rounding heuristic; + +\verb|GLP_OFF| --- disable applying the simple rounding heuristic. + +\newpage + +{\tt int fp\_heur} (default: {\tt GLP\_OFF}) + +Feasibility pump heuristic option: + +\verb|GLP_ON | --- enable applying the feasibility pump heuristic; + +\verb|GLP_OFF| --- disable applying the feasibility pump heuristic. + +\bigskip + +{\tt int ps\_heur} (default: {\tt GLP\_OFF}) + +Proximity search heuristic\footnote{The Fischetti--Monaci Proximity +Search (a.k.a. Proxy) heuristic. This algorithm is often capable of +rapidly improving a feasible solution of a MIP problem with binary +variables. It allows to quickly obtain suboptimal solutions in some +problems which take too long time to be solved to optimality.} option: + +\verb|GLP_ON | --- enable applying the proximity search heuristic; + +\verb|GLP_OFF| --- disable applying the proximity search pump heuristic. + +\bigskip + +{\tt int ps\_tm\_lim} (default: {\tt 60000}) + +Time limit, in milliseconds, for the proximity search heuristic (see +above). + +\bigskip + +{\tt int gmi\_cuts} (default: {\tt GLP\_OFF}) + +Gomory's mixed integer cut option: + +\verb|GLP_ON | --- enable generating Gomory's cuts; + +\verb|GLP_OFF| --- disable generating Gomory's cuts. + +\bigskip + +{\tt int mir\_cuts} (default: {\tt GLP\_OFF}) + +Mixed integer rounding (MIR) cut option: + +\verb|GLP_ON | --- enable generating MIR cuts; + +\verb|GLP_OFF| --- disable generating MIR cuts. + +\bigskip + +{\tt int cov\_cuts} (default: {\tt GLP\_OFF}) + +Mixed cover cut option: + +\verb|GLP_ON | --- enable generating mixed cover cuts; + +\verb|GLP_OFF| --- disable generating mixed cover cuts. + +\bigskip + +{\tt int clq\_cuts} (default: {\tt GLP\_OFF}) + +Clique cut option: + +\verb|GLP_ON | --- enable generating clique cuts; + +\verb|GLP_OFF| --- disable generating clique cuts. + +\newpage + +{\tt double tol\_int} (default: {\tt 1e-5}) + +Absolute tolerance used to check if optimal solution to the current LP +relaxation is integer feasible. (Do not change this parameter without +detailed understanding its purpose.) + +\bigskip + +{\tt double tol\_obj} (default: {\tt 1e-7}) + +Relative tolerance used to check if the objective value in optimal +solution to the current LP relaxation is not better than in the best +known integer feasible solution. (Do not change this parameter without +detailed understanding its purpose.) + +\bigskip + +{\tt double mip\_gap} (default: {\tt 0.0}) + +The relative mip gap tolerance. If the relative mip gap for currently +known best integer feasible solution falls below this tolerance, the +solver terminates the search. This allows obtainig suboptimal integer +feasible solutions if solving the problem to optimality takes too long +time. + +\bigskip + +{\tt int tm\_lim} (default: {\tt INT\_MAX}) + +Searching time limit, in milliseconds. + +\bigskip + +{\tt int out\_frq} (default: {\tt 5000}) + +Output frequency, in milliseconds. This parameter specifies how +frequently the solver sends information about the solution process to +the terminal. + +\bigskip + +{\tt int out\_dly} (default: {\tt 10000}) + +Output delay, in milliseconds. This parameter specifies how long the +solver should delay sending information about solution of the current +LP relaxation with the simplex method to the terminal. + +\bigskip + +{\tt void (*cb\_func)(glp\_tree *tree, void *info)} +(default: {\tt NULL}) + +Entry point to the user-defined callback routine. \verb|NULL| means +the advanced solver interface is not used. For more details see Chapter +``Branch-and-Cut API Routines''. + +\bigskip + +{\tt void *cb\_info} (default: {\tt NULL}) + +Transit pointer passed to the routine \verb|cb_func| (see above). + +\bigskip + +{\tt int cb\_size} (default: {\tt 0}) + +The number of extra (up to 256) bytes allocated for each node of the +branch-and-bound tree to store application-specific data. On creating +a node these bytes are initialized by binary zeros. + +\bigskip + +{\tt int presolve} (default: {\tt GLP\_OFF}) + +MIP presolver option: + +\verb|GLP_ON | --- enable using the MIP presolver; + +\verb|GLP_OFF| --- disable using the MIP presolver. + +\newpage + +{\tt int binarize} (default: {\tt GLP\_OFF}) + +Binarization option (used only if the presolver is enabled): + +\verb|GLP_ON | --- replace general integer variables by binary ones; + +\verb|GLP_OFF| --- do not use binarization. + +\subsection{glp\_init\_iocp --- initialize integer optimizer control +parameters} + +\synopsis + +\begin{verbatim} + void glp_init_iocp(glp_iocp *parm); +\end{verbatim} + +\description + +The routine \verb|glp_init_iocp| initializes control parameters, which +are used by the branch-and-cut solver, with default values. + +Default values of the control parameters are stored in +a \verb|glp_iocp| structure, which the parameter \verb|parm| points to. + +\subsection{glp\_mip\_status --- determine status of MIP solution} + +\synopsis + +\begin{verbatim} + int glp_mip_status(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_mip_status| reports the status of a MIP solution +found by the MIP solver as follows: + +\verb|GLP_UNDEF | --- MIP solution is undefined; + +\verb|GLP_OPT | --- MIP solution is integer optimal; + +\verb|GLP_FEAS | --- MIP solution is integer feasible, however, its +optimality (or non-optimality) has not been proven, perhaps due to +premature termination of the search; + +\verb|GLP_NOFEAS| --- problem has no integer feasible solution (proven +by the solver). + +\subsection{glp\_mip\_obj\_val --- retrieve objective value} + +\synopsis + +\begin{verbatim} + double glp_mip_obj_val(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_mip_obj_val| returns value of the objective +function for MIP solution. + +\newpage + +\subsection{glp\_mip\_row\_val --- retrieve row value} + +\synopsis + +\begin{verbatim} + double glp_mip_row_val(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_mip_row_val| returns value of the auxiliary +variable associated with \verb|i|-th row for MIP solution. + +\subsection{glp\_mip\_col\_val --- retrieve column value} + +\synopsis + +\begin{verbatim} + double glp_mip_col_val(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_mip_col_val| returns value of the structural +variable associated with \verb|j|-th column for MIP solution. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Additional routines} + +\subsection{glp\_check\_kkt --- check feasibility/optimality +conditions} + +\synopsis + +{\parskip=0pt +\tt void glp\_check\_kkt(glp\_prob *P, int sol, int cond, +double *ae\_max, int *ae\_ind, + +\hspace{105pt}double *re\_max, int *re\_ind);} + +\description + +The routine \verb|glp_check_kkt| allows to check +feasibility/optimality conditions for the current solution stored in +the specified problem object. (For basic and interior-point solutions +these conditions are known as {\it Karush--Kuhn--Tucker optimality +conditions}.) + +The parameter \verb|sol| specifies which solution should be checked: + +\verb|GLP_SOL| --- basic solution; + +\verb|GLP_IPT| --- interior-point solution; + +\verb|GLP_MIP| --- mixed integer solution. + +The parameter \verb|cond| specifies which condition should be checked: + +\verb|GLP_KKT_PE| --- check primal equality constraints (KKT.PE); + +\verb|GLP_KKT_PB| --- check primal bound constraints (KKT.PB); + +\verb|GLP_KKT_DE| --- check dual equality constraints (KKT.DE). This +conditions can be checked only for basic or interior-point solution; + +\verb|GLP_KKT_DB| --- check dual bound constraints (KKT.DB). This +conditions can be checked only for basic or interior-point solution. + +Detailed explanations of these conditions are given below in paragraph +``Background''. + +On exit the routine stores the following information to locations +specified by parameters \verb|ae_max|, \verb|ae_ind|, \verb|re_max|, +and \verb|re_ind| (if some parameter is a null pointer, corresponding +information is not stored): + +\verb|ae_max| --- largest absolute error; + +\verb|ae_ind| --- number of row (KKT.PE), column (KKT.DE), or variable +(KKT.PB, KKT.DB) with the largest absolute error; + +\verb|re_max| --- largest relative error; + +\verb|re_ind| --- number of row (KKT.PE), column (KKT.DE), or variable +(KKT.PB, KKT.DB) with the largest relative error. + +Row (auxiliary variable) numbers are in the range 1 to $m$, where $m$ +is the number of rows in the problem object. Column (structural +variable) numbers are in the range 1 to $n$, where $n$ is the number +of columns in the problem object. Variable numbers are in the range +1 to $m+n$, where variables with numbers 1 to $m$ correspond to rows, +and variables with numbers $m+1$ to $m+n$ correspond to columns. If +the error reported is exact zero, corresponding row, column or variable +number is set to zero. + +\newpage + +\para{Background} + +\def\arraystretch{1.5} + +The first condition checked by the routine is the following: +$$x_R - A x_S = 0, \eqno{\rm (KKT.PE)}$$ +where $x_R$ is the subvector of auxiliary variables (rows), $x_S$ is +the subvector of structural variables (columns), $A$ is the constraint +matrix. This condition expresses the requirement that all primal +variables should satisfy to the system of equality constraints of the +original LP problem. In case of exact arithmetic this condition would +be satisfied for any basic solution; however, in case of inexact +(floating-point) arithmetic, this condition shows how accurate the +primal solution is, that depends on accuracy of a representation of the +basis matrix used by the simplex method, or on accuracy provided by the +interior-point method. + +To check the condition (KKT.PE) the routine computes the vector of +residuals: +$$g = x_R - A x_S,$$ +and determines component of this vector that correspond to largest +absolute and relative errors: +$${\tt ae\_max}=\max_{1\leq i\leq m}|g_i|,$$ +$${\tt re\_max}=\max_{1\leq i\leq m}\frac{|g_i|}{1+|(x_R)_i|}.$$ + +The second condition checked by the routine is the following: +$$l_k \leq x_k \leq u_k {\rm \ \ \ for\ all}\ k=1,\dots,m+n, +\eqno{\rm (KKT.PB)}$$ +where $x_k$ is auxiliary ($1\leq k\leq m$) or structural +($m+1\leq k\leq m+n$) variable, $l_k$ and $u_k$ are, respectively, +lower and upper bounds of the variable $x_k$ (including cases of +infinite bounds). This condition expresses the requirement that all +primal variables shoudl satisfy to bound constraints of the original +LP problem. In case of basic solution all non-basic variables are +placed on their active bounds, so actually the condition (KKT.PB) needs +to be checked for basic variables only. If the primal solution has +sufficient accuracy, this condition shows its primal feasibility. + +To check the condition (KKT.PB) the routine computes a vector of +residuals: +$$ +h_k = \left\{ +\begin{array}{ll} +0, & {\rm if}\ l_k \leq x_k \leq u_k \\ +x_k - l_k, & {\rm if}\ x_k < l_k \\ +x_k - u_k, & {\rm if}\ x_k > u_k \\ +\end{array} +\right. +$$ +for all $k=1,\dots,m+n$, and determines components of this vector that +correspond to largest absolute and relative errors: +$${\tt ae\_max}=\max_{1\leq k \leq m+n}|h_k|,$$ +$${\tt re\_max}=\max_{1\leq k \leq m+n}\frac{|h_k|}{1+|x_k|}.$$ + +\newpage + +The third condition checked by the routine is: +$${\rm grad}\;Z = c = (\tilde{A})^T \pi + d,$$ +where $Z$ is the objective function, $c$ is the vector of objective +coefficients, $(\tilde{A})^T$ is a matrix transposed to the expanded +constraint matrix $\tilde{A} = (I|-A)$, $\pi$ is a vector of Lagrange +multipliers that correspond to equality constraints of the original LP +problem, $d$ is a vector of Lagrange multipliers that correspond to +bound constraints for all (auxiliary and structural) variables of the +original LP problem. Geometrically the third condition expresses the +requirement that the gradient of the objective function should belong +to the orthogonal complement of a linear subspace defined by the +equality and active bound constraints, i.e. that the gradient is +a linear combination of normals to the constraint hyperplanes, where +Lagrange multipliers $\pi$ and $d$ are coefficients of that linear +combination. + +To eliminate the vector $\pi$ rewrite the third condition as: +$$ +\left(\begin{array}{@{}c@{}}I \\ -A^T\end{array}\right) \pi = +\left(\begin{array}{@{}c@{}}d_R \\ d_S\end{array}\right) + +\left(\begin{array}{@{}c@{}}c_R \\ c_S\end{array}\right), +$$ +or, equivalently, +$$ +\left\{ +\begin{array}{r@{}c@{}c} +\pi + d_R&\ =\ &c_R, \\ +-A^T\pi + d_S&\ =\ &c_S. \\ +\end{array} +\right. +$$ + +Then substituting the vector $\pi$ from the first equation into the +second we finally have: +$$A^T (d_R - c_R) + (d_S - c_S) = 0, \eqno{\rm(KKT.DE)}$$ +where $d_R$ is the subvector of reduced costs of auxiliary variables +(rows), $d_S$ is the subvector of reduced costs of structural variables +(columns), $c_R$ and $c_S$ are subvectors of objective coefficients at, +respectively, auxiliary and structural variables, $A^T$ is a matrix +transposed to the constraint matrix of the original LP problem. In case +of exact arithmetic this condition would be satisfied for any basic +solution; however, in case of inexact (floating-point) arithmetic, this +condition shows how accurate the dual solution is, that depends on +accuracy of a representation of the basis matrix used by the simplex +method, or on accuracy provided by the interior-point method. + +To check the condition (KKT.DE) the routine computes a vector of +residuals: +$$u = A^T (d_R - c_R) + (d_S - c_S),$$ +and determines components of this vector that correspond to largest +absolute and relative errors: +$${\tt ae\_max}=\max_{1\leq j\leq n}|u_j|,$$ +$${\tt re\_max}=\max_{1\leq j\leq n}\frac{|u_j|}{1+|(d_S)_j-(c_S)_j|}.$$ + +\newpage + +The fourth condition checked by the routine is the following: +$$ +\left\{ +\begin{array}{l@{\ }r@{\ }c@{\ }c@{\ }c@{\ }l@{\ }c@{\ }c@{\ }c@{\ }l} +{\rm if} & -\infty & < & x_k & < & +\infty, +& {\rm then} & d_k & = & 0 \\ +{\rm if} & l_k & \leq & x_k & < & +\infty, +& {\rm then} & d_k & \geq & 0\ {\rm(minimization)} \\ +&&&&&& & d_k & \leq & 0\ {\rm(maximization)} \\ +{\rm if} & -\infty & < & x_k & \leq & u_k, +& {\rm then} & d_k & \leq & 0\ {\rm(minimization)} \\ +&&&&&& & d_k & \geq & 0\ {\rm(maximization)} \\ +{\rm if} & l_k & \leq & x_k & \leq & u_k, +& {\rm then} & d_k & {\rm is} & {\rm of\ any\ sign} \\ +\end{array}\right.\eqno{\rm(KKT.DB)} +$$ +for all $k=1,\dots,m+n$, where $d_k$ is a reduced cost (Lagrange +multiplier) of auxiliary ($1\leq k\leq m$) or structural +($m+1\leq k\leq m+n$) variable $x_k$. Geometrically this condition +expresses the requirement that constraints of the original problem must +``hold'' the point preventing its movement along the anti-gradient (in +case of minimization) or the gradient (in case of maximization) of the +objective function. In case of basic solution reduced costs of all +basic variables are placed on their active (zero) bounds, so actually +the condition (KKT.DB) needs to be checked for non-basic variables +only. If the dual solution has sufficient accuracy, this condition +shows the dual feasibility of the solution. + +To check the condition (KKT.DB) the routine computes a vector of +residuals: +$$ +v_k = \left\{ +\begin{array}{ll} +0, & {\rm if}\ d_k\ {\rm has\ correct\ sign} \\ +|d_k|, & {\rm if}\ d_k\ {\rm has\ wrong\ sign} \\ +\end{array} +\right. +$$ +for all $k=1,\dots,m+n$, and determines components of this vector that +correspond to largest absolute and relative errors: +$${\tt ae\_max}=\max_{1\leq k\leq m+n}|v_k|,$$ +$${\tt re\_max}=\max_{1\leq k\leq m+n}\frac{|v_k|}{1+|d_k - c_k|}.$$ + +Note that the complete set of Karush-Kuhn-Tucker optimality conditions +also includes the fifth, so called {\it complementary slackness +condition}, which expresses the requirement that at least either +a primal variable $x_k$ or its dual counterpart $d_k$ should be on its +bound for all $k=1,\dots,m+n$. Currently checking this condition is +not implemented yet. + +\def\arraystretch{1} + +%* eof *% |