alpar@1
|
1 |
%* glpk02.tex *%
|
alpar@1
|
2 |
|
alpar@1
|
3 |
\chapter{Basic API Routines}
|
alpar@1
|
4 |
|
alpar@1
|
5 |
This chapter describes GLPK API routines intended for using in
|
alpar@1
|
6 |
application programs.
|
alpar@1
|
7 |
|
alpar@1
|
8 |
\subsubsection*{Library header}
|
alpar@1
|
9 |
|
alpar@1
|
10 |
All GLPK API data types and routines are defined in the header file
|
alpar@1
|
11 |
\verb|glpk.h|. It should be included in all source files which use
|
alpar@1
|
12 |
GLPK API, either directly or indirectly through some other header file
|
alpar@1
|
13 |
as follows:
|
alpar@1
|
14 |
|
alpar@1
|
15 |
\begin{verbatim}
|
alpar@1
|
16 |
#include <glpk.h>
|
alpar@1
|
17 |
\end{verbatim}
|
alpar@1
|
18 |
|
alpar@1
|
19 |
\subsubsection*{Error handling}
|
alpar@1
|
20 |
|
alpar@1
|
21 |
If some GLPK API routine detects erroneous or incorrect data passed by
|
alpar@1
|
22 |
the application program, it writes appropriate diagnostic messages to
|
alpar@1
|
23 |
the terminal and then abnormally terminates the application program.
|
alpar@1
|
24 |
In most practical cases this allows to simplify programming by avoiding
|
alpar@1
|
25 |
numerous checks of return codes. Thus, in order to prevent crashing the
|
alpar@1
|
26 |
application program should check all data, which are suspected to be
|
alpar@1
|
27 |
incorrect, before calling GLPK API routines.
|
alpar@1
|
28 |
|
alpar@1
|
29 |
Should note that this kind of error handling is used only in cases of
|
alpar@1
|
30 |
incorrect data passed by the application program. If, for example, the
|
alpar@1
|
31 |
application program calls some GLPK API routine to read data from an
|
alpar@1
|
32 |
input file and these data are incorrect, the GLPK API routine reports
|
alpar@1
|
33 |
about error in the usual way by means of the return code.
|
alpar@1
|
34 |
|
alpar@1
|
35 |
\subsubsection*{Thread safety}
|
alpar@1
|
36 |
|
alpar@1
|
37 |
Currently GLPK API routines are non-reentrant and therefore cannot be
|
alpar@1
|
38 |
used in multi-threaded programs.
|
alpar@1
|
39 |
|
alpar@1
|
40 |
\subsubsection*{Array indexing}
|
alpar@1
|
41 |
|
alpar@1
|
42 |
Normally all GLPK API routines start array indexing from 1, not from 0
|
alpar@1
|
43 |
(except the specially stipulated cases). This means, for example, that
|
alpar@1
|
44 |
if some vector $x$ of the length $n$ is passed as an array to some GLPK
|
alpar@1
|
45 |
API routine, the latter expects vector components to be placed in
|
alpar@1
|
46 |
locations \verb|x[1]|, \verb|x[2]|, \dots, \verb|x[n]|, and the location
|
alpar@1
|
47 |
\verb|x[0]| normally is not used.
|
alpar@1
|
48 |
|
alpar@1
|
49 |
In order to avoid indexing errors it is most convenient and most
|
alpar@1
|
50 |
reliable to declare the array \verb|x| as follows:
|
alpar@1
|
51 |
|
alpar@1
|
52 |
\begin{verbatim}
|
alpar@1
|
53 |
double x[1+n];
|
alpar@1
|
54 |
\end{verbatim}
|
alpar@1
|
55 |
|
alpar@1
|
56 |
\noindent
|
alpar@1
|
57 |
or to allocate it as follows:
|
alpar@1
|
58 |
|
alpar@1
|
59 |
\begin{verbatim}
|
alpar@1
|
60 |
double *x;
|
alpar@1
|
61 |
. . .
|
alpar@1
|
62 |
x = calloc(1+n, sizeof(double));
|
alpar@1
|
63 |
\end{verbatim}
|
alpar@1
|
64 |
|
alpar@1
|
65 |
\noindent
|
alpar@1
|
66 |
In both cases one extra location \verb|x[0]| is reserved that allows
|
alpar@1
|
67 |
passing the array to GLPK routines in a usual way.
|
alpar@1
|
68 |
|
alpar@1
|
69 |
\section{Problem object}
|
alpar@1
|
70 |
|
alpar@1
|
71 |
All GLPK API routines deal with so called {\it problem object}, which
|
alpar@1
|
72 |
is a program object of type \verb|glp_prob| and intended to represent
|
alpar@1
|
73 |
a particular LP or MIP instance.
|
alpar@1
|
74 |
|
alpar@1
|
75 |
The type \verb|glp_prob| is a data structure declared in the header
|
alpar@1
|
76 |
file \verb|glpk.h| as follows:
|
alpar@1
|
77 |
|
alpar@1
|
78 |
\begin{verbatim}
|
alpar@1
|
79 |
typedef struct { ... } glp_prob;
|
alpar@1
|
80 |
\end{verbatim}
|
alpar@1
|
81 |
|
alpar@1
|
82 |
Problem objects (i.e. program objects of the \verb|glp_prob| type) are
|
alpar@1
|
83 |
allocated and managed internally by the GLPK API routines. The
|
alpar@1
|
84 |
application program should never use any members of the \verb|glp_prob|
|
alpar@1
|
85 |
structure directly and should deal only with pointers to these objects
|
alpar@1
|
86 |
(that is, \verb|glp_prob *| values).
|
alpar@1
|
87 |
|
alpar@1
|
88 |
\pagebreak
|
alpar@1
|
89 |
|
alpar@1
|
90 |
The problem object consists of five segments, which are:
|
alpar@1
|
91 |
|
alpar@1
|
92 |
$\bullet$ problem segment,
|
alpar@1
|
93 |
|
alpar@1
|
94 |
$\bullet$ basis segment,
|
alpar@1
|
95 |
|
alpar@1
|
96 |
$\bullet$ interior point segment,
|
alpar@1
|
97 |
|
alpar@1
|
98 |
$\bullet$ MIP segment, and
|
alpar@1
|
99 |
|
alpar@1
|
100 |
$\bullet$ control parameters and statistics segment.
|
alpar@1
|
101 |
|
alpar@1
|
102 |
\subsubsection*{Problem segment}
|
alpar@1
|
103 |
|
alpar@1
|
104 |
The {\it problem segment} contains original LP/MIP data, which
|
alpar@1
|
105 |
corresponds to the problem formulation (1.1)---(1.3) (see Section
|
alpar@1
|
106 |
\ref{seclp}, page \pageref{seclp}). It includes the following
|
alpar@1
|
107 |
components:
|
alpar@1
|
108 |
|
alpar@1
|
109 |
$\bullet$ rows (auxiliary variables),
|
alpar@1
|
110 |
|
alpar@1
|
111 |
$\bullet$ columns (structural variables),
|
alpar@1
|
112 |
|
alpar@1
|
113 |
$\bullet$ objective function, and
|
alpar@1
|
114 |
|
alpar@1
|
115 |
$\bullet$ constraint matrix.
|
alpar@1
|
116 |
|
alpar@1
|
117 |
Rows and columns have the same set of the following attributes:
|
alpar@1
|
118 |
|
alpar@1
|
119 |
$\bullet$ ordinal number,
|
alpar@1
|
120 |
|
alpar@1
|
121 |
$\bullet$ symbolic name (1 up to 255 arbitrary graphic characters),
|
alpar@1
|
122 |
|
alpar@1
|
123 |
$\bullet$ type (free, lower bound, upper bound, double bound, fixed),
|
alpar@1
|
124 |
|
alpar@1
|
125 |
$\bullet$ numerical values of lower and upper bounds,
|
alpar@1
|
126 |
|
alpar@1
|
127 |
$\bullet$ scale factor.
|
alpar@1
|
128 |
|
alpar@1
|
129 |
{\it Ordinal numbers} are intended for referencing rows and columns.
|
alpar@1
|
130 |
Row ordinal numbers are integers $1, 2, \dots, m$, and column ordinal
|
alpar@1
|
131 |
numbers are integers $1, 2, \dots, n$, where $m$ and $n$ are,
|
alpar@1
|
132 |
respectively, the current number of rows and columns in the problem
|
alpar@1
|
133 |
object.
|
alpar@1
|
134 |
|
alpar@1
|
135 |
{\it Symbolic names} are intended for informational purposes. They also
|
alpar@1
|
136 |
can be used for referencing rows and columns.
|
alpar@1
|
137 |
|
alpar@1
|
138 |
{\it Types and bounds} of rows (auxiliary variables) and columns
|
alpar@1
|
139 |
(structural variables) are explained above (see Section \ref{seclp},
|
alpar@1
|
140 |
page \pageref{seclp}).
|
alpar@1
|
141 |
|
alpar@1
|
142 |
{\it Scale factors} are used internally for scaling rows and columns of
|
alpar@1
|
143 |
the constraint matrix.
|
alpar@1
|
144 |
|
alpar@1
|
145 |
Information about the {\it objective function} includes numerical
|
alpar@1
|
146 |
values of objective coefficients and a flag, which defines the
|
alpar@1
|
147 |
optimization direction (i.e. minimization or maximization).
|
alpar@1
|
148 |
|
alpar@1
|
149 |
The {\it constraint matrix} is a $m \times n$ rectangular matrix built
|
alpar@1
|
150 |
of constraint coefficients $a_{ij}$, which defines the system of linear
|
alpar@1
|
151 |
constraints (1.2) (see Section \ref{seclp}, page \pageref{seclp}). This
|
alpar@1
|
152 |
matrix is stored in the problem object in both row-wise and column-wise
|
alpar@1
|
153 |
sparse formats.
|
alpar@1
|
154 |
|
alpar@1
|
155 |
Once the problem object has been created, the application program can
|
alpar@1
|
156 |
access and modify any components of the problem segment in arbitrary
|
alpar@1
|
157 |
order.
|
alpar@1
|
158 |
|
alpar@1
|
159 |
\subsubsection*{Basis segment}
|
alpar@1
|
160 |
|
alpar@1
|
161 |
The {\it basis segment} of the problem object keeps information related
|
alpar@1
|
162 |
to the current basic solution. It includes:
|
alpar@1
|
163 |
|
alpar@1
|
164 |
$\bullet$ row and column statuses,
|
alpar@1
|
165 |
|
alpar@1
|
166 |
$\bullet$ basic solution statuses,
|
alpar@1
|
167 |
|
alpar@1
|
168 |
$\bullet$ factorization of the current basis matrix, and
|
alpar@1
|
169 |
|
alpar@1
|
170 |
$\bullet$ basic solution components.
|
alpar@1
|
171 |
|
alpar@1
|
172 |
The {\it row and column statuses} define which rows and columns are
|
alpar@1
|
173 |
basic and which are non-basic. These statuses may be assigned either by
|
alpar@1
|
174 |
the application program of by some API routines. Note that these
|
alpar@1
|
175 |
statuses are always defined independently on whether the corresponding
|
alpar@1
|
176 |
basis is valid or not.
|
alpar@1
|
177 |
|
alpar@1
|
178 |
The {\it basic solution statuses} include the {\it primal status} and
|
alpar@1
|
179 |
the {\it dual status}, which are set by the simplex-based solver once
|
alpar@1
|
180 |
the problem has been solved. The primal status shows whether a primal
|
alpar@1
|
181 |
basic solution is feasible, infeasible, or undefined. The dual status
|
alpar@1
|
182 |
shows the same for a dual basic solution.
|
alpar@1
|
183 |
|
alpar@1
|
184 |
The {\it factorization of the basis matrix} is some factorized form
|
alpar@1
|
185 |
(like LU-factorization) of the current basis matrix (defined by the
|
alpar@1
|
186 |
current row and column statuses). The factorization is used by the
|
alpar@1
|
187 |
simplex-based solver and kept when the solver terminates the search.
|
alpar@1
|
188 |
This feature allows efficiently reoptimizing the problem after some
|
alpar@1
|
189 |
modifications (for example, after changing some bounds or objective
|
alpar@1
|
190 |
coefficients). It also allows performing the post-optimal analysis (for
|
alpar@1
|
191 |
example, computing components of the simplex table, etc.).
|
alpar@1
|
192 |
|
alpar@1
|
193 |
The {\it basic solution components} include primal and dual values of
|
alpar@1
|
194 |
all auxiliary and structural variables for the most recently obtained
|
alpar@1
|
195 |
basic solution.
|
alpar@1
|
196 |
|
alpar@1
|
197 |
\subsubsection*{Interior point segment}
|
alpar@1
|
198 |
|
alpar@1
|
199 |
The {\it interior point segment} is automatically allocated after the
|
alpar@1
|
200 |
problem has been solved using the interior point solver. It contains
|
alpar@1
|
201 |
interior point solution components, which include the solution status,
|
alpar@1
|
202 |
and primal and dual values of all auxiliary and structural variables.
|
alpar@1
|
203 |
|
alpar@1
|
204 |
\subsubsection*{MIP segment}
|
alpar@1
|
205 |
|
alpar@1
|
206 |
The {\it MIP segment} is used only for MIP problems. This segment
|
alpar@1
|
207 |
includes:
|
alpar@1
|
208 |
|
alpar@1
|
209 |
$\bullet$ column kinds,
|
alpar@1
|
210 |
|
alpar@1
|
211 |
$\bullet$ MIP solution status, and
|
alpar@1
|
212 |
|
alpar@1
|
213 |
$\bullet$ MIP solution components.
|
alpar@1
|
214 |
|
alpar@1
|
215 |
The {\it column kinds} define which columns (i.e. structural variables)
|
alpar@1
|
216 |
are integer and which are continuous.
|
alpar@1
|
217 |
|
alpar@1
|
218 |
The {\it MIP solution status} is set by the MIP solver and shows whether
|
alpar@1
|
219 |
a MIP solution is integer optimal, integer feasible (non-optimal), or
|
alpar@1
|
220 |
undefined.
|
alpar@1
|
221 |
|
alpar@1
|
222 |
The {\it MIP solution components} are computed by the MIP solver and
|
alpar@1
|
223 |
include primal values of all auxiliary and structural variables for the
|
alpar@1
|
224 |
most recently obtained MIP solution.
|
alpar@1
|
225 |
|
alpar@1
|
226 |
Note that in case of MIP problem the basis segment corresponds to
|
alpar@1
|
227 |
the optimal solution of LP relaxation, which is also available to the
|
alpar@1
|
228 |
application program.
|
alpar@1
|
229 |
|
alpar@1
|
230 |
Currently the search tree is not kept in the MIP segment. Therefore if
|
alpar@1
|
231 |
the search has been terminated, it cannot be continued.
|
alpar@1
|
232 |
|
alpar@1
|
233 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
alpar@1
|
234 |
|
alpar@1
|
235 |
\newpage
|
alpar@1
|
236 |
|
alpar@1
|
237 |
\section{Problem creating and modifying routines}
|
alpar@1
|
238 |
|
alpar@1
|
239 |
\subsection{glp\_create\_prob---create problem object}
|
alpar@1
|
240 |
|
alpar@1
|
241 |
\subsubsection*{Synopsis}
|
alpar@1
|
242 |
|
alpar@1
|
243 |
\begin{verbatim}
|
alpar@1
|
244 |
glp_prob *glp_create_prob(void);
|
alpar@1
|
245 |
\end{verbatim}
|
alpar@1
|
246 |
|
alpar@1
|
247 |
\subsubsection*{Description}
|
alpar@1
|
248 |
|
alpar@1
|
249 |
The routine \verb|glp_create_prob| creates a new problem object, which
|
alpar@1
|
250 |
initially is ``empty'', i.e. has no rows and columns.
|
alpar@1
|
251 |
|
alpar@1
|
252 |
\subsubsection*{Returns}
|
alpar@1
|
253 |
|
alpar@1
|
254 |
The routine returns a pointer to the created object, which should be
|
alpar@1
|
255 |
used in any subsequent operations on this object.
|
alpar@1
|
256 |
|
alpar@1
|
257 |
\subsection{glp\_set\_prob\_name---assign (change) problem name}
|
alpar@1
|
258 |
|
alpar@1
|
259 |
\subsubsection*{Synopsis}
|
alpar@1
|
260 |
|
alpar@1
|
261 |
\begin{verbatim}
|
alpar@1
|
262 |
void glp_set_prob_name(glp_prob *lp, const char *name);
|
alpar@1
|
263 |
\end{verbatim}
|
alpar@1
|
264 |
|
alpar@1
|
265 |
\subsubsection*{Description}
|
alpar@1
|
266 |
|
alpar@1
|
267 |
The routine \verb|glp_set_prob_name| assigns a given symbolic
|
alpar@1
|
268 |
\verb|name| (1 up to 255 characters) to the specified problem object.
|
alpar@1
|
269 |
|
alpar@1
|
270 |
If the parameter \verb|name| is \verb|NULL| or empty string, the routine
|
alpar@1
|
271 |
erases an existing symbolic name of the problem object.
|
alpar@1
|
272 |
|
alpar@1
|
273 |
\subsection{glp\_set\_obj\_name---assign (change) objective function
|
alpar@1
|
274 |
name}
|
alpar@1
|
275 |
|
alpar@1
|
276 |
\subsubsection*{Synopsis}
|
alpar@1
|
277 |
|
alpar@1
|
278 |
\begin{verbatim}
|
alpar@1
|
279 |
void glp_set_obj_name(glp_prob *lp, const char *name);
|
alpar@1
|
280 |
\end{verbatim}
|
alpar@1
|
281 |
|
alpar@1
|
282 |
\subsubsection*{Description}
|
alpar@1
|
283 |
|
alpar@1
|
284 |
The routine \verb|glp_set_obj_name| assigns a given symbolic
|
alpar@1
|
285 |
\verb|name| (1 up to 255 characters) to the objective function of the
|
alpar@1
|
286 |
specified problem object.
|
alpar@1
|
287 |
|
alpar@1
|
288 |
If the parameter \verb|name| is \verb|NULL| or empty string, the routine
|
alpar@1
|
289 |
erases an existing symbolic name of the objective function.
|
alpar@1
|
290 |
|
alpar@1
|
291 |
\subsection{glp\_set\_obj\_dir---set (change) optimization direction\\
|
alpar@1
|
292 |
flag}
|
alpar@1
|
293 |
|
alpar@1
|
294 |
\subsubsection*{Synopsis}
|
alpar@1
|
295 |
|
alpar@1
|
296 |
\begin{verbatim}
|
alpar@1
|
297 |
void glp_set_obj_dir(glp_prob *lp, int dir);
|
alpar@1
|
298 |
\end{verbatim}
|
alpar@1
|
299 |
|
alpar@1
|
300 |
\subsubsection*{Description}
|
alpar@1
|
301 |
|
alpar@1
|
302 |
The routine \verb|glp_set_obj_dir| sets (changes) the optimization
|
alpar@1
|
303 |
direction flag (i.e. ``sense'' of the objective function) as specified
|
alpar@1
|
304 |
by the parameter \verb|dir|:
|
alpar@1
|
305 |
|
alpar@1
|
306 |
\begin{tabular}{@{}ll}
|
alpar@1
|
307 |
\verb|GLP_MIN| & minimization; \\
|
alpar@1
|
308 |
\verb|GLP_MAX| & maximization. \\
|
alpar@1
|
309 |
\end{tabular}
|
alpar@1
|
310 |
|
alpar@1
|
311 |
\noindent
|
alpar@1
|
312 |
(Note that by default the problem is minimization.)
|
alpar@1
|
313 |
|
alpar@1
|
314 |
\subsection{glp\_add\_rows---add new rows to problem object}
|
alpar@1
|
315 |
|
alpar@1
|
316 |
\subsubsection*{Synopsis}
|
alpar@1
|
317 |
|
alpar@1
|
318 |
\begin{verbatim}
|
alpar@1
|
319 |
int glp_add_rows(glp_prob *lp, int nrs);
|
alpar@1
|
320 |
\end{verbatim}
|
alpar@1
|
321 |
|
alpar@1
|
322 |
\subsubsection*{Description}
|
alpar@1
|
323 |
|
alpar@1
|
324 |
The routine \verb|glp_add_rows| adds \verb|nrs| rows (constraints) to
|
alpar@1
|
325 |
the specified problem object. New rows are always added to the end of
|
alpar@1
|
326 |
the row list, so the ordinal numbers of existing rows are not changed.
|
alpar@1
|
327 |
|
alpar@1
|
328 |
Being added each new row is initially free (unbounded) and has empty
|
alpar@1
|
329 |
list of the constraint coefficients.
|
alpar@1
|
330 |
|
alpar@1
|
331 |
\subsubsection*{Returns}
|
alpar@1
|
332 |
|
alpar@1
|
333 |
The routine \verb|glp_add_rows| returns the ordinal number of the first
|
alpar@1
|
334 |
new row added to the problem object.
|
alpar@1
|
335 |
|
alpar@1
|
336 |
\newpage
|
alpar@1
|
337 |
|
alpar@1
|
338 |
\subsection{glp\_add\_cols---add new columns to problem object}
|
alpar@1
|
339 |
|
alpar@1
|
340 |
\subsubsection*{Synopsis}
|
alpar@1
|
341 |
|
alpar@1
|
342 |
\begin{verbatim}
|
alpar@1
|
343 |
int glp_add_cols(glp_prob *lp, int ncs);
|
alpar@1
|
344 |
\end{verbatim}
|
alpar@1
|
345 |
|
alpar@1
|
346 |
\subsubsection*{Description}
|
alpar@1
|
347 |
|
alpar@1
|
348 |
The routine \verb|glp_add_cols| adds \verb|ncs| columns (structural
|
alpar@1
|
349 |
variables) to the specified problem object. New columns are always added
|
alpar@1
|
350 |
to the end of the column list, so the ordinal numbers of existing
|
alpar@1
|
351 |
columns are not changed.
|
alpar@1
|
352 |
|
alpar@1
|
353 |
Being added each new column is initially fixed at zero and has empty
|
alpar@1
|
354 |
list of the constraint coefficients.
|
alpar@1
|
355 |
|
alpar@1
|
356 |
\subsubsection*{Returns}
|
alpar@1
|
357 |
|
alpar@1
|
358 |
The routine \verb|glp_add_cols| returns the ordinal number of the first
|
alpar@1
|
359 |
new column added to the problem object.
|
alpar@1
|
360 |
|
alpar@1
|
361 |
\subsection{glp\_set\_row\_name---assign (change) row name}
|
alpar@1
|
362 |
|
alpar@1
|
363 |
\subsubsection*{Synopsis}
|
alpar@1
|
364 |
|
alpar@1
|
365 |
\begin{verbatim}
|
alpar@1
|
366 |
void glp_set_row_name(glp_prob *lp, int i, const char *name);
|
alpar@1
|
367 |
\end{verbatim}
|
alpar@1
|
368 |
|
alpar@1
|
369 |
\subsubsection*{Description}
|
alpar@1
|
370 |
|
alpar@1
|
371 |
The routine \verb|glp_set_row_name| assigns a given symbolic
|
alpar@1
|
372 |
\verb|name| (1 up to 255 characters) to \verb|i|-th row (auxiliary
|
alpar@1
|
373 |
variable) of the specified problem object.
|
alpar@1
|
374 |
|
alpar@1
|
375 |
If the parameter \verb|name| is \verb|NULL| or empty string, the routine
|
alpar@1
|
376 |
erases an existing name of $i$-th row.
|
alpar@1
|
377 |
|
alpar@1
|
378 |
\subsection{glp\_set\_col\_name---assign (change) column name}
|
alpar@1
|
379 |
|
alpar@1
|
380 |
\subsubsection*{Synopsis}
|
alpar@1
|
381 |
|
alpar@1
|
382 |
\begin{verbatim}
|
alpar@1
|
383 |
void glp_set_col_name(glp_prob *lp, int j, const char *name);
|
alpar@1
|
384 |
\end{verbatim}
|
alpar@1
|
385 |
|
alpar@1
|
386 |
\subsubsection*{Description}
|
alpar@1
|
387 |
|
alpar@1
|
388 |
The routine \verb|glp_set_col_name| assigns a given symbolic
|
alpar@1
|
389 |
\verb|name| (1 up to 255 characters) to \verb|j|-th column (structural
|
alpar@1
|
390 |
variable) of the specified problem object.
|
alpar@1
|
391 |
|
alpar@1
|
392 |
If the parameter \verb|name| is \verb|NULL| or empty string, the routine
|
alpar@1
|
393 |
erases an existing name of $j$-th column.
|
alpar@1
|
394 |
|
alpar@1
|
395 |
\subsection{glp\_set\_row\_bnds---set (change) row bounds}
|
alpar@1
|
396 |
|
alpar@1
|
397 |
\subsubsection*{Synopsis}
|
alpar@1
|
398 |
|
alpar@1
|
399 |
\begin{verbatim}
|
alpar@1
|
400 |
void glp_set_row_bnds(glp_prob *lp, int i, int type,
|
alpar@1
|
401 |
double lb, double ub);
|
alpar@1
|
402 |
\end{verbatim}
|
alpar@1
|
403 |
|
alpar@1
|
404 |
\subsubsection*{Description}
|
alpar@1
|
405 |
|
alpar@1
|
406 |
The routine \verb|glp_set_row_bnds| sets (changes) the type and bounds
|
alpar@1
|
407 |
of \verb|i|-th row (auxiliary variable) of the specified problem object.
|
alpar@1
|
408 |
|
alpar@1
|
409 |
The parameters \verb|type|, \verb|lb|, and \verb|ub| specify the type,
|
alpar@1
|
410 |
lower bound, and upper bound, respectively, as follows:
|
alpar@1
|
411 |
|
alpar@1
|
412 |
\begin{center}
|
alpar@1
|
413 |
\begin{tabular}{cr@{}c@{}ll}
|
alpar@1
|
414 |
Type & \multicolumn{3}{c}{Bounds} & Comment \\
|
alpar@1
|
415 |
\hline
|
alpar@1
|
416 |
\verb|GLP_FR| & $-\infty <$ &$\ x\ $& $< +\infty$
|
alpar@1
|
417 |
& Free (unbounded) variable \\
|
alpar@1
|
418 |
\verb|GLP_LO| & $lb \leq$ &$\ x\ $& $< +\infty$
|
alpar@1
|
419 |
& Variable with lower bound \\
|
alpar@1
|
420 |
\verb|GLP_UP| & $-\infty <$ &$\ x\ $& $\leq ub$
|
alpar@1
|
421 |
& Variable with upper bound \\
|
alpar@1
|
422 |
\verb|GLP_DB| & $lb \leq$ &$\ x\ $& $\leq ub$
|
alpar@1
|
423 |
& Double-bounded variable \\
|
alpar@1
|
424 |
\verb|GLP_FX| & $lb =$ &$\ x\ $& $= ub$
|
alpar@1
|
425 |
& Fixed variable \\
|
alpar@1
|
426 |
\end{tabular}
|
alpar@1
|
427 |
\end{center}
|
alpar@1
|
428 |
|
alpar@1
|
429 |
\noindent
|
alpar@1
|
430 |
where $x$ is the auxiliary variable associated with $i$-th row.
|
alpar@1
|
431 |
|
alpar@1
|
432 |
If the row has no lower bound, the parameter \verb|lb| is ignored. If
|
alpar@1
|
433 |
the row has no upper bound, the parameter \verb|ub| is ignored. If the
|
alpar@1
|
434 |
row is an equality constraint (i.e. the corresponding auxiliary variable
|
alpar@1
|
435 |
is of fixed type), only the parameter \verb|lb| is used while the
|
alpar@1
|
436 |
parameter \verb|ub| is ignored.
|
alpar@1
|
437 |
|
alpar@1
|
438 |
Being added to the problem object each row is initially free, i.e. its
|
alpar@1
|
439 |
type is \verb|GLP_FR|.
|
alpar@1
|
440 |
|
alpar@1
|
441 |
\newpage
|
alpar@1
|
442 |
|
alpar@1
|
443 |
\subsection{glp\_set\_col\_bnds---set (change) column bounds}
|
alpar@1
|
444 |
|
alpar@1
|
445 |
\subsubsection*{Synopsis}
|
alpar@1
|
446 |
|
alpar@1
|
447 |
\begin{verbatim}
|
alpar@1
|
448 |
void glp_set_col_bnds(glp_prob *lp, int j, int type,
|
alpar@1
|
449 |
double lb, double ub);
|
alpar@1
|
450 |
\end{verbatim}
|
alpar@1
|
451 |
|
alpar@1
|
452 |
\subsubsection*{Description}
|
alpar@1
|
453 |
|
alpar@1
|
454 |
The routine \verb|glp_set_col_bnds| sets (changes) the type and bounds
|
alpar@1
|
455 |
of \verb|j|-th column (structural variable) of the specified problem
|
alpar@1
|
456 |
object.
|
alpar@1
|
457 |
|
alpar@1
|
458 |
The parameters \verb|type|, \verb|lb|, and \verb|ub| specify the type,
|
alpar@1
|
459 |
lower bound, and upper bound, respectively, as follows:
|
alpar@1
|
460 |
|
alpar@1
|
461 |
\begin{center}
|
alpar@1
|
462 |
\begin{tabular}{cr@{}c@{}ll}
|
alpar@1
|
463 |
Type & \multicolumn{3}{c}{Bounds} & Comment \\
|
alpar@1
|
464 |
\hline
|
alpar@1
|
465 |
\verb|GLP_FR| & $-\infty <$ &$\ x\ $& $< +\infty$
|
alpar@1
|
466 |
& Free (unbounded) variable \\
|
alpar@1
|
467 |
\verb|GLP_LO| & $lb \leq$ &$\ x\ $& $< +\infty$
|
alpar@1
|
468 |
& Variable with lower bound \\
|
alpar@1
|
469 |
\verb|GLP_UP| & $-\infty <$ &$\ x\ $& $\leq ub$
|
alpar@1
|
470 |
& Variable with upper bound \\
|
alpar@1
|
471 |
\verb|GLP_DB| & $lb \leq$ &$\ x\ $& $\leq ub$
|
alpar@1
|
472 |
& Double-bounded variable \\
|
alpar@1
|
473 |
\verb|GLP_FX| & $lb =$ &$\ x\ $& $= ub$
|
alpar@1
|
474 |
& Fixed variable \\
|
alpar@1
|
475 |
\end{tabular}
|
alpar@1
|
476 |
\end{center}
|
alpar@1
|
477 |
|
alpar@1
|
478 |
\noindent
|
alpar@1
|
479 |
where $x$ is the structural variable associated with $j$-th column.
|
alpar@1
|
480 |
|
alpar@1
|
481 |
If the column has no lower bound, the parameter \verb|lb| is ignored.
|
alpar@1
|
482 |
If the column has no upper bound, the parameter \verb|ub| is ignored.
|
alpar@1
|
483 |
If the column is of fixed type, only the parameter \verb|lb| is used
|
alpar@1
|
484 |
while the parameter \verb|ub| is ignored.
|
alpar@1
|
485 |
|
alpar@1
|
486 |
Being added to the problem object each column is initially fixed at
|
alpar@1
|
487 |
zero, i.e. its type is \verb|GLP_FX| and both bounds are 0.
|
alpar@1
|
488 |
|
alpar@1
|
489 |
\subsection{glp\_set\_obj\_coef---set (change) objective coefficient
|
alpar@1
|
490 |
or constant term}
|
alpar@1
|
491 |
|
alpar@1
|
492 |
\subsubsection*{Synopsis}
|
alpar@1
|
493 |
|
alpar@1
|
494 |
\begin{verbatim}
|
alpar@1
|
495 |
void glp_set_obj_coef(glp_prob *lp, int j, double coef);
|
alpar@1
|
496 |
\end{verbatim}
|
alpar@1
|
497 |
|
alpar@1
|
498 |
\subsubsection*{Description}
|
alpar@1
|
499 |
|
alpar@1
|
500 |
The routine \verb|glp_set_obj_coef| sets (changes) the objective
|
alpar@1
|
501 |
coefficient at \verb|j|-th column (structural variable). A new value of
|
alpar@1
|
502 |
the objective coefficient is specified by the parameter \verb|coef|.
|
alpar@1
|
503 |
|
alpar@1
|
504 |
If the parameter \verb|j| is 0, the routine sets (changes) the constant
|
alpar@1
|
505 |
term (``shift'') of the objective function.
|
alpar@1
|
506 |
|
alpar@1
|
507 |
\subsection{glp\_set\_mat\_row---set (replace) row of the constraint
|
alpar@1
|
508 |
matrix}
|
alpar@1
|
509 |
|
alpar@1
|
510 |
\subsubsection*{Synopsis}
|
alpar@1
|
511 |
|
alpar@1
|
512 |
\begin{verbatim}
|
alpar@1
|
513 |
void glp_set_mat_row(glp_prob *lp, int i, int len,
|
alpar@1
|
514 |
const int ind[], const double val[]);
|
alpar@1
|
515 |
\end{verbatim}
|
alpar@1
|
516 |
|
alpar@1
|
517 |
\subsubsection*{Description}
|
alpar@1
|
518 |
|
alpar@1
|
519 |
The routine \verb|glp_set_mat_row| stores (replaces) the contents of
|
alpar@1
|
520 |
\verb|i|-th row of the constraint matrix of the specified problem
|
alpar@1
|
521 |
object.
|
alpar@1
|
522 |
|
alpar@1
|
523 |
Column indices and numerical values of new row elements must be placed
|
alpar@1
|
524 |
in locations \verb|ind[1]|, \dots, \verb|ind[len]| and \verb|val[1]|,
|
alpar@1
|
525 |
\dots, \verb|val[len]|, respectively, where $0 \leq$ \verb|len| $\leq n$
|
alpar@1
|
526 |
is the new length of $i$-th row, $n$ is the current number of columns in
|
alpar@1
|
527 |
the problem object. Elements with identical column indices are not
|
alpar@1
|
528 |
allowed. Zero elements are allowed, but they are not stored in the
|
alpar@1
|
529 |
constraint matrix.
|
alpar@1
|
530 |
|
alpar@1
|
531 |
If the parameter \verb|len| is 0, the parameters \verb|ind| and/or
|
alpar@1
|
532 |
\verb|val| can be specified as \verb|NULL|.
|
alpar@1
|
533 |
|
alpar@1
|
534 |
\subsection{glp\_set\_mat\_col---set (replace) column of the
|
alpar@1
|
535 |
constr\-aint matrix}
|
alpar@1
|
536 |
|
alpar@1
|
537 |
\subsubsection*{Synopsis}
|
alpar@1
|
538 |
|
alpar@1
|
539 |
\begin{verbatim}
|
alpar@1
|
540 |
void glp_set_mat_col(glp_prob *lp, int j, int len,
|
alpar@1
|
541 |
const int ind[], const double val[]);
|
alpar@1
|
542 |
\end{verbatim}
|
alpar@1
|
543 |
|
alpar@1
|
544 |
\subsubsection*{Description}
|
alpar@1
|
545 |
|
alpar@1
|
546 |
The routine \verb|glp_set_mat_col| stores (replaces) the contents of
|
alpar@1
|
547 |
\verb|j|-th column of the constraint matrix of the specified problem
|
alpar@1
|
548 |
object.
|
alpar@1
|
549 |
|
alpar@1
|
550 |
Row indices and numerical values of new column elements must be placed
|
alpar@1
|
551 |
in locations \verb|ind[1]|, \dots, \verb|ind[len]| and \verb|val[1]|,
|
alpar@1
|
552 |
\dots, \verb|val[len]|, respectively, where $0 \leq$ \verb|len| $\leq m$
|
alpar@1
|
553 |
is the new length of $j$-th column, $m$ is the current number of rows in
|
alpar@1
|
554 |
the problem object. Elements with identical row indices are not allowed.
|
alpar@1
|
555 |
Zero elements are allowed, but they are not stored in the constraint
|
alpar@1
|
556 |
matrix.
|
alpar@1
|
557 |
|
alpar@1
|
558 |
If the parameter \verb|len| is 0, the parameters \verb|ind| and/or
|
alpar@1
|
559 |
\verb|val| can be specified as \verb|NULL|.
|
alpar@1
|
560 |
|
alpar@1
|
561 |
\subsection{glp\_load\_matrix---load (replace) the whole constraint
|
alpar@1
|
562 |
matrix}
|
alpar@1
|
563 |
|
alpar@1
|
564 |
\subsubsection*{Synopsis}
|
alpar@1
|
565 |
|
alpar@1
|
566 |
\begin{verbatim}
|
alpar@1
|
567 |
void glp_load_matrix(glp_prob *lp, int ne, const int ia[],
|
alpar@1
|
568 |
const int ja[], const double ar[]);
|
alpar@1
|
569 |
\end{verbatim}
|
alpar@1
|
570 |
|
alpar@1
|
571 |
\subsubsection*{Description}
|
alpar@1
|
572 |
|
alpar@1
|
573 |
The routine \verb|glp_load_matrix| loads the constraint matrix passed
|
alpar@1
|
574 |
in the arrays \verb|ia|, \verb|ja|, and \verb|ar| into the specified
|
alpar@1
|
575 |
problem object. Before loading the current contents of the constraint
|
alpar@1
|
576 |
matrix is destroyed.
|
alpar@1
|
577 |
|
alpar@1
|
578 |
Constraint coefficients (elements of the constraint matrix) must be
|
alpar@1
|
579 |
specified as triplets (\verb|ia[k]|, \verb|ja[k]|, \verb|ar[k]|) for
|
alpar@1
|
580 |
$k=1,\dots,ne$, where \verb|ia[k]| is the row index, \verb|ja[k]| is
|
alpar@1
|
581 |
the column index, and \verb|ar[k]| is a numeric value of corresponding
|
alpar@1
|
582 |
constraint coefficient. The parameter \verb|ne| specifies the total
|
alpar@1
|
583 |
number of (non-zero) elements in the matrix to be loaded. Coefficients
|
alpar@1
|
584 |
with identical indices are not allowed. Zero coefficients are allowed,
|
alpar@1
|
585 |
however, they are not stored in the constraint matrix.
|
alpar@1
|
586 |
|
alpar@1
|
587 |
If the parameter \verb|ne| is 0, the parameters \verb|ia|, \verb|ja|,
|
alpar@1
|
588 |
and/or \verb|ar| can be specified as \verb|NULL|.
|
alpar@1
|
589 |
|
alpar@1
|
590 |
\subsection{glp\_check\_dup---check for duplicate elements in sparse
|
alpar@1
|
591 |
matrix}
|
alpar@1
|
592 |
|
alpar@1
|
593 |
\subsubsection*{Synopsis}
|
alpar@1
|
594 |
|
alpar@1
|
595 |
\begin{verbatim}
|
alpar@1
|
596 |
int glp_check_dup(int m, int n, int ne, const int ia[],
|
alpar@1
|
597 |
const int ja[]);
|
alpar@1
|
598 |
\end{verbatim}
|
alpar@1
|
599 |
|
alpar@1
|
600 |
\subsubsection*{Description}
|
alpar@1
|
601 |
|
alpar@1
|
602 |
The routine \verb|glp_check_dup checks| for duplicate elements (that
|
alpar@1
|
603 |
is, elements with identical indices) in a sparse matrix specified in
|
alpar@1
|
604 |
the coordinate format.
|
alpar@1
|
605 |
|
alpar@1
|
606 |
The parameters $m$ and $n$ specifies, respectively, the number of rows
|
alpar@1
|
607 |
and columns in the matrix, $m\geq 0$, $n\geq 0$.
|
alpar@1
|
608 |
|
alpar@1
|
609 |
The parameter {\it ne} specifies the number of (structurally) non-zero
|
alpar@1
|
610 |
elements in the matrix, {\it ne} $\geq 0$.
|
alpar@1
|
611 |
|
alpar@1
|
612 |
Elements of the matrix are specified as doublets $(ia[k],ja[k])$ for
|
alpar@1
|
613 |
$k=1,\dots,ne$, where $ia[k]$ is a row index, $ja[k]$ is a column index.
|
alpar@1
|
614 |
|
alpar@1
|
615 |
The routine \verb|glp_check_dup| can be used prior to a call to the
|
alpar@1
|
616 |
routine \verb|glp_load_matrix| to check that the constraint matrix to
|
alpar@1
|
617 |
be loaded has no duplicate elements.
|
alpar@1
|
618 |
|
alpar@1
|
619 |
\subsubsection*{Returns}
|
alpar@1
|
620 |
|
alpar@1
|
621 |
The routine \verb|glp_check_dup| returns one of the following values:
|
alpar@1
|
622 |
|
alpar@1
|
623 |
\noindent
|
alpar@1
|
624 |
\begin{tabular}{@{}r@{\ }c@{\ }l@{}}
|
alpar@1
|
625 |
0&---&the matrix has no duplicate elements;\\
|
alpar@1
|
626 |
$-k$&---&indices $ia[k]$ or/and $ja[k]$ are out of range;\\
|
alpar@1
|
627 |
$+k$&---&element $(ia[k],ja[k])$ is duplicate.\\
|
alpar@1
|
628 |
\end{tabular}
|
alpar@1
|
629 |
|
alpar@1
|
630 |
\subsection{glp\_sort\_matrix---sort elements of the constraint matrix}
|
alpar@1
|
631 |
|
alpar@1
|
632 |
\subsubsection*{Synopsis}
|
alpar@1
|
633 |
|
alpar@1
|
634 |
\begin{verbatim}
|
alpar@1
|
635 |
void glp_sort_matrix(glp_prob *P);
|
alpar@1
|
636 |
\end{verbatim}
|
alpar@1
|
637 |
|
alpar@1
|
638 |
\subsubsection*{Description}
|
alpar@1
|
639 |
|
alpar@1
|
640 |
The routine \verb|glp_sort_matrix| sorts elements of the constraint
|
alpar@1
|
641 |
matrix rebuilding its row and column linked lists. On exit from the
|
alpar@1
|
642 |
routine the constraint matrix is not changed, however, elements in the
|
alpar@1
|
643 |
row linked lists become ordered by ascending column indices, and the
|
alpar@1
|
644 |
elements in the column linked lists become ordered by ascending row
|
alpar@1
|
645 |
indices.
|
alpar@1
|
646 |
|
alpar@1
|
647 |
\subsection{glp\_del\_rows---delete rows from problem object}
|
alpar@1
|
648 |
|
alpar@1
|
649 |
\subsubsection*{Synopsis}
|
alpar@1
|
650 |
|
alpar@1
|
651 |
\begin{verbatim}
|
alpar@1
|
652 |
void glp_del_rows(glp_prob *lp, int nrs, const int num[]);
|
alpar@1
|
653 |
\end{verbatim}
|
alpar@1
|
654 |
|
alpar@1
|
655 |
\subsubsection*{Description}
|
alpar@1
|
656 |
|
alpar@1
|
657 |
The routine \verb|glp_del_rows| deletes rows from the specified problem
|
alpar@1
|
658 |
ob-\linebreak ject. Ordinal numbers of rows to be deleted should be
|
alpar@1
|
659 |
placed in locations \verb|num[1]|, \dots, \verb|num[nrs]|, where
|
alpar@1
|
660 |
${\tt nrs}>0$.
|
alpar@1
|
661 |
|
alpar@1
|
662 |
Note that deleting rows involves changing ordinal numbers of other
|
alpar@1
|
663 |
rows remaining in the problem object. New ordinal numbers of the
|
alpar@1
|
664 |
remaining rows are assigned under the assumption that the original
|
alpar@1
|
665 |
order of rows is not changed. Let, for example, before deletion there
|
alpar@1
|
666 |
be five rows $a$, $b$, $c$, $d$, $e$ with ordinal numbers 1, 2, 3, 4, 5,
|
alpar@1
|
667 |
and let rows $b$ and $d$ have been deleted. Then after deletion the
|
alpar@1
|
668 |
remaining rows $a$, $c$, $e$ are assigned new oridinal numbers 1, 2, 3.
|
alpar@1
|
669 |
|
alpar@1
|
670 |
\subsection{glp\_del\_cols---delete columns from problem object}
|
alpar@1
|
671 |
|
alpar@1
|
672 |
\subsubsection*{Synopsis}
|
alpar@1
|
673 |
|
alpar@1
|
674 |
\begin{verbatim}
|
alpar@1
|
675 |
void glp_del_cols(glp_prob *lp, int ncs, const int num[]);
|
alpar@1
|
676 |
\end{verbatim}
|
alpar@1
|
677 |
|
alpar@1
|
678 |
\subsubsection*{Description}
|
alpar@1
|
679 |
|
alpar@1
|
680 |
The routine \verb|glp_del_cols| deletes columns from the specified
|
alpar@1
|
681 |
problem object. Ordinal numbers of columns to be deleted should be
|
alpar@1
|
682 |
placed in locations \verb|num[1]|, \dots, \verb|num[ncs]|, where
|
alpar@1
|
683 |
${\tt ncs}>0$.
|
alpar@1
|
684 |
|
alpar@1
|
685 |
Note that deleting columns involves changing ordinal numbers of other
|
alpar@1
|
686 |
columns remaining in the problem object. New ordinal numbers of the
|
alpar@1
|
687 |
remaining columns are assigned under the assumption that the original
|
alpar@1
|
688 |
order of columns is not changed. Let, for example, before deletion there
|
alpar@1
|
689 |
be six columns $p$, $q$, $r$, $s$, $t$, $u$ with ordinal numbers 1, 2,
|
alpar@1
|
690 |
3, 4, 5, 6, and let columns $p$, $q$, $s$ have been deleted. Then after
|
alpar@1
|
691 |
deletion the remaining columns $r$, $t$, $u$ are assigned new ordinal
|
alpar@1
|
692 |
numbers 1, 2, 3.
|
alpar@1
|
693 |
|
alpar@1
|
694 |
\subsection{glp\_copy\_prob---copy problem object content}
|
alpar@1
|
695 |
|
alpar@1
|
696 |
\subsubsection*{Synopsis}
|
alpar@1
|
697 |
|
alpar@1
|
698 |
\begin{verbatim}
|
alpar@1
|
699 |
void glp_copy_prob(glp_prob *dest, glp_prob *prob, int names);
|
alpar@1
|
700 |
\end{verbatim}
|
alpar@1
|
701 |
|
alpar@1
|
702 |
\subsubsection*{Description}
|
alpar@1
|
703 |
|
alpar@1
|
704 |
The routine \verb|glp_copy_prob| copies the content of the problem
|
alpar@1
|
705 |
object \verb|prob| to the problem object \verb|dest|.
|
alpar@1
|
706 |
|
alpar@1
|
707 |
The parameter \verb|names| is a flag. If it is \verb|GLP_ON|,
|
alpar@1
|
708 |
the routine also copies all symbolic names; otherwise, if it is
|
alpar@1
|
709 |
\verb|GLP_OFF|, no symbolic names are copied.
|
alpar@1
|
710 |
|
alpar@1
|
711 |
\newpage
|
alpar@1
|
712 |
|
alpar@1
|
713 |
\subsection{glp\_erase\_prob---erase problem object content}
|
alpar@1
|
714 |
|
alpar@1
|
715 |
\subsubsection*{Synopsis}
|
alpar@1
|
716 |
|
alpar@1
|
717 |
\begin{verbatim}
|
alpar@1
|
718 |
void glp_erase_prob(glp_prob *lp);
|
alpar@1
|
719 |
\end{verbatim}
|
alpar@1
|
720 |
|
alpar@1
|
721 |
\subsubsection*{Description}
|
alpar@1
|
722 |
|
alpar@1
|
723 |
The routine \verb|glp_erase_prob| erases the content of the specified
|
alpar@1
|
724 |
problem object. The effect of this operation is the same as if the
|
alpar@1
|
725 |
problem object would be deleted with the routine \verb|glp_delete_prob|
|
alpar@1
|
726 |
and then created anew with the routine \verb|glp_create_prob|, with the
|
alpar@1
|
727 |
only exception that the handle (pointer) to the problem object remains
|
alpar@1
|
728 |
valid.
|
alpar@1
|
729 |
|
alpar@1
|
730 |
\subsection{glp\_delete\_prob---delete problem object}
|
alpar@1
|
731 |
|
alpar@1
|
732 |
\subsubsection*{Synopsis}
|
alpar@1
|
733 |
|
alpar@1
|
734 |
\begin{verbatim}
|
alpar@1
|
735 |
void glp_delete_prob(glp_prob *lp);
|
alpar@1
|
736 |
\end{verbatim}
|
alpar@1
|
737 |
|
alpar@1
|
738 |
\subsubsection*{Description}
|
alpar@1
|
739 |
|
alpar@1
|
740 |
The routine \verb|glp_delete_prob| deletes a problem object, which the
|
alpar@1
|
741 |
parameter \verb|lp| points to, freeing all the memory allocated to this
|
alpar@1
|
742 |
object.
|
alpar@1
|
743 |
|
alpar@1
|
744 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
alpar@1
|
745 |
|
alpar@1
|
746 |
\newpage
|
alpar@1
|
747 |
|
alpar@1
|
748 |
\section{Problem retrieving routines}
|
alpar@1
|
749 |
|
alpar@1
|
750 |
\subsection{glp\_get\_prob\_name---retrieve problem name}
|
alpar@1
|
751 |
|
alpar@1
|
752 |
\subsubsection*{Synopsis}
|
alpar@1
|
753 |
|
alpar@1
|
754 |
\begin{verbatim}
|
alpar@1
|
755 |
const char *glp_get_prob_name(glp_prob *lp);
|
alpar@1
|
756 |
\end{verbatim}
|
alpar@1
|
757 |
|
alpar@1
|
758 |
\subsubsection*{Returns}
|
alpar@1
|
759 |
|
alpar@1
|
760 |
The routine \verb|glp_get_prob_name| returns a pointer to an internal
|
alpar@1
|
761 |
buffer, which contains symbolic name of the problem. However, if the
|
alpar@1
|
762 |
problem has no assigned name, the routine returns \verb|NULL|.
|
alpar@1
|
763 |
|
alpar@1
|
764 |
\subsection{glp\_get\_obj\_name---retrieve objective function name}
|
alpar@1
|
765 |
|
alpar@1
|
766 |
\subsubsection*{Synopsis}
|
alpar@1
|
767 |
|
alpar@1
|
768 |
\begin{verbatim}
|
alpar@1
|
769 |
const char *glp_get_obj_name(glp_prob *lp);
|
alpar@1
|
770 |
\end{verbatim}
|
alpar@1
|
771 |
|
alpar@1
|
772 |
\subsubsection*{Returns}
|
alpar@1
|
773 |
|
alpar@1
|
774 |
The routine \verb|glp_get_obj_name| returns a pointer to an internal
|
alpar@1
|
775 |
buffer, which contains symbolic name assigned to the objective
|
alpar@1
|
776 |
function. However, if the objective function has no assigned name, the
|
alpar@1
|
777 |
routine returns \verb|NULL|.
|
alpar@1
|
778 |
|
alpar@1
|
779 |
\subsection{glp\_get\_obj\_dir---retrieve optimization direction flag}
|
alpar@1
|
780 |
|
alpar@1
|
781 |
\subsubsection*{Synopsis}
|
alpar@1
|
782 |
|
alpar@1
|
783 |
\begin{verbatim}
|
alpar@1
|
784 |
int glp_get_obj_dir(glp_prob *lp);
|
alpar@1
|
785 |
\end{verbatim}
|
alpar@1
|
786 |
|
alpar@1
|
787 |
\subsubsection*{Returns}
|
alpar@1
|
788 |
|
alpar@1
|
789 |
The routine \verb|glp_get_obj_dir| returns the optimization direction
|
alpar@1
|
790 |
flag (i.e. ``sense'' of the objective function):
|
alpar@1
|
791 |
|
alpar@1
|
792 |
\begin{tabular}{@{}ll}
|
alpar@1
|
793 |
\verb|GLP_MIN| & minimization; \\
|
alpar@1
|
794 |
\verb|GLP_MAX| & maximization. \\
|
alpar@1
|
795 |
\end{tabular}
|
alpar@1
|
796 |
|
alpar@1
|
797 |
\pagebreak
|
alpar@1
|
798 |
|
alpar@1
|
799 |
\subsection{glp\_get\_num\_rows---retrieve number of rows}
|
alpar@1
|
800 |
|
alpar@1
|
801 |
\subsubsection*{Synopsis}
|
alpar@1
|
802 |
|
alpar@1
|
803 |
\begin{verbatim}
|
alpar@1
|
804 |
int glp_get_num_rows(glp_prob *lp);
|
alpar@1
|
805 |
\end{verbatim}
|
alpar@1
|
806 |
|
alpar@1
|
807 |
\subsubsection*{Returns}
|
alpar@1
|
808 |
|
alpar@1
|
809 |
The routine \verb|glp_get_num_rows| returns the current number of rows
|
alpar@1
|
810 |
in the specified problem object.
|
alpar@1
|
811 |
|
alpar@1
|
812 |
\subsection{glp\_get\_num\_cols---retrieve number of columns}
|
alpar@1
|
813 |
|
alpar@1
|
814 |
\subsubsection*{Synopsis}
|
alpar@1
|
815 |
|
alpar@1
|
816 |
\begin{verbatim}
|
alpar@1
|
817 |
int glp_get_num_cols(glp_prob *lp);
|
alpar@1
|
818 |
\end{verbatim}
|
alpar@1
|
819 |
|
alpar@1
|
820 |
\subsubsection*{Returns}
|
alpar@1
|
821 |
|
alpar@1
|
822 |
The routine \verb|glp_get_num_cols| returns the current number of
|
alpar@1
|
823 |
columns the specified problem object.
|
alpar@1
|
824 |
|
alpar@1
|
825 |
\subsection{glp\_get\_row\_name---retrieve row name}
|
alpar@1
|
826 |
|
alpar@1
|
827 |
\subsubsection*{Synopsis}
|
alpar@1
|
828 |
|
alpar@1
|
829 |
\begin{verbatim}
|
alpar@1
|
830 |
const char *glp_get_row_name(glp_prob *lp, int i);
|
alpar@1
|
831 |
\end{verbatim}
|
alpar@1
|
832 |
|
alpar@1
|
833 |
\subsubsection*{Returns}
|
alpar@1
|
834 |
|
alpar@1
|
835 |
The routine \verb|glp_get_row_name| returns a pointer to an internal
|
alpar@1
|
836 |
buffer, which contains a symbolic name assigned to \verb|i|-th row.
|
alpar@1
|
837 |
However, if the row has no assigned name, the routine returns
|
alpar@1
|
838 |
\verb|NULL|.
|
alpar@1
|
839 |
|
alpar@1
|
840 |
\subsection{glp\_get\_col\_name---retrieve column name}
|
alpar@1
|
841 |
|
alpar@1
|
842 |
\subsubsection*{Synopsis}
|
alpar@1
|
843 |
|
alpar@1
|
844 |
\begin{verbatim}
|
alpar@1
|
845 |
const char *glp_get_col_name(glp_prob *lp, int j);
|
alpar@1
|
846 |
\end{verbatim}
|
alpar@1
|
847 |
|
alpar@1
|
848 |
\subsubsection*{Returns}
|
alpar@1
|
849 |
|
alpar@1
|
850 |
The routine \verb|glp_get_col_name| returns a pointer to an internal
|
alpar@1
|
851 |
buffer, which contains a symbolic name assigned to \verb|j|-th column.
|
alpar@1
|
852 |
However, if the column has no assigned name, the routine returns
|
alpar@1
|
853 |
\verb|NULL|.
|
alpar@1
|
854 |
|
alpar@1
|
855 |
\subsection{glp\_get\_row\_type---retrieve row type}
|
alpar@1
|
856 |
|
alpar@1
|
857 |
\subsubsection*{Synopsis}
|
alpar@1
|
858 |
|
alpar@1
|
859 |
\begin{verbatim}
|
alpar@1
|
860 |
int glp_get_row_type(glp_prob *lp, int i);
|
alpar@1
|
861 |
\end{verbatim}
|
alpar@1
|
862 |
|
alpar@1
|
863 |
\subsubsection*{Returns}
|
alpar@1
|
864 |
|
alpar@1
|
865 |
The routine \verb|glp_get_row_type| returns the type of \verb|i|-th
|
alpar@1
|
866 |
row, i.e. the type of corresponding auxiliary variable, as follows:
|
alpar@1
|
867 |
|
alpar@1
|
868 |
\begin{tabular}{@{}ll}
|
alpar@1
|
869 |
\verb|GLP_FR| & free (unbounded) variable; \\
|
alpar@1
|
870 |
\verb|GLP_LO| & variable with lower bound; \\
|
alpar@1
|
871 |
\verb|GLP_UP| & variable with upper bound; \\
|
alpar@1
|
872 |
\verb|GLP_DB| & double-bounded variable; \\
|
alpar@1
|
873 |
\verb|GLP_FX| & fixed variable. \\
|
alpar@1
|
874 |
\end{tabular}
|
alpar@1
|
875 |
|
alpar@1
|
876 |
\subsection{glp\_get\_row\_lb---retrieve row lower bound}
|
alpar@1
|
877 |
|
alpar@1
|
878 |
\subsubsection*{Synopsis}
|
alpar@1
|
879 |
|
alpar@1
|
880 |
\begin{verbatim}
|
alpar@1
|
881 |
double glp_get_row_lb(glp_prob *lp, int i);
|
alpar@1
|
882 |
\end{verbatim}
|
alpar@1
|
883 |
|
alpar@1
|
884 |
\subsubsection*{Returns}
|
alpar@1
|
885 |
|
alpar@1
|
886 |
The routine \verb|glp_get_row_lb| returns the lower bound of
|
alpar@1
|
887 |
\verb|i|-th row, i.e. the lower bound of corresponding auxiliary
|
alpar@1
|
888 |
variable. However, if the row has no lower bound, the routine returns
|
alpar@1
|
889 |
\verb|-DBL_MAX|.
|
alpar@1
|
890 |
|
alpar@1
|
891 |
\subsection{glp\_get\_row\_ub---retrieve row upper bound}
|
alpar@1
|
892 |
|
alpar@1
|
893 |
\subsubsection*{Synopsis}
|
alpar@1
|
894 |
|
alpar@1
|
895 |
\begin{verbatim}
|
alpar@1
|
896 |
double glp_get_row_ub(glp_prob *lp, int i);
|
alpar@1
|
897 |
\end{verbatim}
|
alpar@1
|
898 |
|
alpar@1
|
899 |
\subsubsection*{Returns}
|
alpar@1
|
900 |
|
alpar@1
|
901 |
The routine \verb|glp_get_row_ub| returns the upper bound of
|
alpar@1
|
902 |
\verb|i|-th row, i.e. the upper bound of corresponding auxiliary
|
alpar@1
|
903 |
variable. However, if the row has no upper bound, the routine returns
|
alpar@1
|
904 |
\verb|+DBL_MAX|.
|
alpar@1
|
905 |
|
alpar@1
|
906 |
\subsection{glp\_get\_col\_type---retrieve column type}
|
alpar@1
|
907 |
|
alpar@1
|
908 |
\subsubsection*{Synopsis}
|
alpar@1
|
909 |
|
alpar@1
|
910 |
\begin{verbatim}
|
alpar@1
|
911 |
int glp_get_col_type(glp_prob *lp, int j);
|
alpar@1
|
912 |
\end{verbatim}
|
alpar@1
|
913 |
|
alpar@1
|
914 |
\subsubsection*{Returns}
|
alpar@1
|
915 |
|
alpar@1
|
916 |
The routine \verb|glp_get_col_type| returns the type of \verb|j|-th
|
alpar@1
|
917 |
column, i.e. the type of corresponding structural variable, as follows:
|
alpar@1
|
918 |
|
alpar@1
|
919 |
\begin{tabular}{@{}ll}
|
alpar@1
|
920 |
\verb|GLP_FR| & free (unbounded) variable; \\
|
alpar@1
|
921 |
\verb|GLP_LO| & variable with lower bound; \\
|
alpar@1
|
922 |
\verb|GLP_UP| & variable with upper bound; \\
|
alpar@1
|
923 |
\verb|GLP_DB| & double-bounded variable; \\
|
alpar@1
|
924 |
\verb|GLP_FX| & fixed variable. \\
|
alpar@1
|
925 |
\end{tabular}
|
alpar@1
|
926 |
|
alpar@1
|
927 |
\subsection{glp\_get\_col\_lb---retrieve column lower bound}
|
alpar@1
|
928 |
|
alpar@1
|
929 |
\subsubsection*{Synopsis}
|
alpar@1
|
930 |
|
alpar@1
|
931 |
\begin{verbatim}
|
alpar@1
|
932 |
double glp_get_col_lb(glp_prob *lp, int j);
|
alpar@1
|
933 |
\end{verbatim}
|
alpar@1
|
934 |
|
alpar@1
|
935 |
\subsubsection*{Returns}
|
alpar@1
|
936 |
|
alpar@1
|
937 |
The routine \verb|glp_get_col_lb| returns the lower bound of
|
alpar@1
|
938 |
\verb|j|-th column, i.e. the lower bound of corresponding structural
|
alpar@1
|
939 |
variable. However, if the column has no lower bound, the routine returns
|
alpar@1
|
940 |
\verb|-DBL_MAX|.
|
alpar@1
|
941 |
|
alpar@1
|
942 |
\subsection{glp\_get\_col\_ub---retrieve column upper bound}
|
alpar@1
|
943 |
|
alpar@1
|
944 |
\subsubsection*{Synopsis}
|
alpar@1
|
945 |
|
alpar@1
|
946 |
\begin{verbatim}
|
alpar@1
|
947 |
double glp_get_col_ub(glp_prob *lp, int j);
|
alpar@1
|
948 |
\end{verbatim}
|
alpar@1
|
949 |
|
alpar@1
|
950 |
\subsubsection*{Returns}
|
alpar@1
|
951 |
|
alpar@1
|
952 |
The routine \verb|glp_get_col_ub| returns the upper bound of
|
alpar@1
|
953 |
\verb|j|-th column, i.e. the upper bound of corresponding structural
|
alpar@1
|
954 |
variable. However, if the column has no upper bound, the routine returns
|
alpar@1
|
955 |
\verb|+DBL_MAX|.
|
alpar@1
|
956 |
|
alpar@1
|
957 |
\subsection{glp\_get\_obj\_coef---retrieve objective coefficient or\\
|
alpar@1
|
958 |
constant term}
|
alpar@1
|
959 |
|
alpar@1
|
960 |
\subsubsection*{Synopsis}
|
alpar@1
|
961 |
|
alpar@1
|
962 |
\begin{verbatim}
|
alpar@1
|
963 |
double glp_get_obj_coef(glp_prob *lp, int j);
|
alpar@1
|
964 |
\end{verbatim}
|
alpar@1
|
965 |
|
alpar@1
|
966 |
\subsubsection*{Returns}
|
alpar@1
|
967 |
|
alpar@1
|
968 |
The routine \verb|glp_get_obj_coef| returns the objective coefficient
|
alpar@1
|
969 |
at \verb|j|-th structural variable (column).
|
alpar@1
|
970 |
|
alpar@1
|
971 |
If the parameter \verb|j| is 0, the routine returns the constant term
|
alpar@1
|
972 |
(``shift'') of the objective function.
|
alpar@1
|
973 |
|
alpar@1
|
974 |
\subsection{glp\_get\_num\_nz---retrieve number of constraint
|
alpar@1
|
975 |
coefficients}
|
alpar@1
|
976 |
|
alpar@1
|
977 |
\subsubsection*{Synopsis}
|
alpar@1
|
978 |
|
alpar@1
|
979 |
\begin{verbatim}
|
alpar@1
|
980 |
int glp_get_num_nz(glp_prob *lp);
|
alpar@1
|
981 |
\end{verbatim}
|
alpar@1
|
982 |
|
alpar@1
|
983 |
\subsubsection*{Returns}
|
alpar@1
|
984 |
|
alpar@1
|
985 |
The routine \verb|glp_get_num_nz| returns the number of non-zero
|
alpar@1
|
986 |
elements in the constraint matrix of the specified problem object.
|
alpar@1
|
987 |
|
alpar@1
|
988 |
\subsection{glp\_get\_mat\_row---retrieve row of the constraint
|
alpar@1
|
989 |
matrix}
|
alpar@1
|
990 |
|
alpar@1
|
991 |
\subsubsection*{Synopsis}
|
alpar@1
|
992 |
|
alpar@1
|
993 |
\begin{verbatim}
|
alpar@1
|
994 |
int glp_get_mat_row(glp_prob *lp, int i, int ind[],
|
alpar@1
|
995 |
double val[]);
|
alpar@1
|
996 |
\end{verbatim}
|
alpar@1
|
997 |
|
alpar@1
|
998 |
\subsubsection*{Description}
|
alpar@1
|
999 |
|
alpar@1
|
1000 |
The routine \verb|glp_get_mat_row| scans (non-zero) elements of
|
alpar@1
|
1001 |
\verb|i|-th row of the constraint matrix of the specified problem object
|
alpar@1
|
1002 |
and stores their column indices and numeric values to locations
|
alpar@1
|
1003 |
\verb|ind[1]|, \dots, \verb|ind[len]| and \verb|val[1]|, \dots,
|
alpar@1
|
1004 |
\verb|val[len]|, respectively, where $0\leq{\tt len}\leq n$ is the
|
alpar@1
|
1005 |
number of elements in $i$-th row, $n$ is the number of columns.
|
alpar@1
|
1006 |
|
alpar@1
|
1007 |
The parameter \verb|ind| and/or \verb|val| can be specified as
|
alpar@1
|
1008 |
\verb|NULL|, in which case corresponding information is not stored.
|
alpar@1
|
1009 |
|
alpar@1
|
1010 |
\subsubsection*{Returns}
|
alpar@1
|
1011 |
|
alpar@1
|
1012 |
The routine \verb|glp_get_mat_row| returns the length \verb|len|, i.e.
|
alpar@1
|
1013 |
the number of (non-zero) elements in \verb|i|-th row.
|
alpar@1
|
1014 |
|
alpar@1
|
1015 |
\subsection{glp\_get\_mat\_col---retrieve column of the constraint\\
|
alpar@1
|
1016 |
matrix}
|
alpar@1
|
1017 |
|
alpar@1
|
1018 |
\subsubsection*{Synopsis}
|
alpar@1
|
1019 |
|
alpar@1
|
1020 |
\begin{verbatim}
|
alpar@1
|
1021 |
int glp_get_mat_col(glp_prob *lp, int j, int ind[],
|
alpar@1
|
1022 |
double val[]);
|
alpar@1
|
1023 |
\end{verbatim}
|
alpar@1
|
1024 |
|
alpar@1
|
1025 |
\subsubsection*{Description}
|
alpar@1
|
1026 |
|
alpar@1
|
1027 |
The routine \verb|glp_get_mat_col| scans (non-zero) elements of
|
alpar@1
|
1028 |
\verb|j|-th column of the constraint matrix of the specified problem
|
alpar@1
|
1029 |
object and stores their row indices and numeric values to locations
|
alpar@1
|
1030 |
\verb|ind[1]|, \dots, \verb|ind[len]| and \verb|val[1]|, \dots,
|
alpar@1
|
1031 |
\verb|val[len]|, respectively, where $0\leq{\tt len}\leq m$ is the
|
alpar@1
|
1032 |
number of elements in $j$-th column, $m$ is the number of rows.
|
alpar@1
|
1033 |
|
alpar@1
|
1034 |
The parameter \verb|ind| and/or \verb|val| can be specified as
|
alpar@1
|
1035 |
\verb|NULL|, in which case corresponding information is not stored.
|
alpar@1
|
1036 |
|
alpar@1
|
1037 |
\subsubsection*{Returns}
|
alpar@1
|
1038 |
|
alpar@1
|
1039 |
The routine \verb|glp_get_mat_col| returns the length \verb|len|, i.e.
|
alpar@1
|
1040 |
the number of (non-zero) elements in \verb|j|-th column.
|
alpar@1
|
1041 |
|
alpar@1
|
1042 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
alpar@1
|
1043 |
|
alpar@1
|
1044 |
\newpage
|
alpar@1
|
1045 |
|
alpar@1
|
1046 |
\section{Row and column searching routines}
|
alpar@1
|
1047 |
|
alpar@1
|
1048 |
\subsection{glp\_create\_index---create the name index}
|
alpar@1
|
1049 |
|
alpar@1
|
1050 |
\subsubsection*{Synopsis}
|
alpar@1
|
1051 |
|
alpar@1
|
1052 |
\begin{verbatim}
|
alpar@1
|
1053 |
void glp_create_index(glp_prob *lp);
|
alpar@1
|
1054 |
\end{verbatim}
|
alpar@1
|
1055 |
|
alpar@1
|
1056 |
\subsubsection*{Description}
|
alpar@1
|
1057 |
|
alpar@1
|
1058 |
The routine \verb|glp_create_index| creates the name index for the
|
alpar@1
|
1059 |
specified problem object. The name index is an auxiliary data structure,
|
alpar@1
|
1060 |
which is intended to quickly (i.e. for logarithmic time) find rows and
|
alpar@1
|
1061 |
columns by their names.
|
alpar@1
|
1062 |
|
alpar@1
|
1063 |
This routine can be called at any time. If the name index already
|
alpar@1
|
1064 |
exists, the routine does nothing.
|
alpar@1
|
1065 |
|
alpar@1
|
1066 |
\subsection{glp\_find\_row---find row by its name}
|
alpar@1
|
1067 |
|
alpar@1
|
1068 |
\subsubsection*{Synopsis}
|
alpar@1
|
1069 |
|
alpar@1
|
1070 |
\begin{verbatim}
|
alpar@1
|
1071 |
int glp_find_row(glp_prob *lp, const char *name);
|
alpar@1
|
1072 |
\end{verbatim}
|
alpar@1
|
1073 |
|
alpar@1
|
1074 |
\subsubsection*{Returns}
|
alpar@1
|
1075 |
|
alpar@1
|
1076 |
The routine \verb|glp_find_row| returns the ordinal number of a row,
|
alpar@1
|
1077 |
which is assigned (by the routine \verb|glp_set_row_name|) the specified
|
alpar@1
|
1078 |
symbolic \verb|name|. If no such row exists, the routine returns 0.
|
alpar@1
|
1079 |
|
alpar@1
|
1080 |
\subsection{glp\_find\_col---find column by its name}
|
alpar@1
|
1081 |
|
alpar@1
|
1082 |
\subsubsection*{Synopsis}
|
alpar@1
|
1083 |
|
alpar@1
|
1084 |
\begin{verbatim}
|
alpar@1
|
1085 |
int glp_find_col(glp_prob *lp, const char *name);
|
alpar@1
|
1086 |
\end{verbatim}
|
alpar@1
|
1087 |
|
alpar@1
|
1088 |
\subsubsection*{Returns}
|
alpar@1
|
1089 |
|
alpar@1
|
1090 |
The routine \verb|glp_find_col| returns the ordinal number of a column,
|
alpar@1
|
1091 |
which is assigned (by the routine \verb|glp_set_col_name|) the specified
|
alpar@1
|
1092 |
symbolic \verb|name|. If no such column exists, the routine returns 0.
|
alpar@1
|
1093 |
|
alpar@1
|
1094 |
\subsection{glp\_delete\_index---delete the name index}
|
alpar@1
|
1095 |
|
alpar@1
|
1096 |
\subsubsection*{Synopsis}
|
alpar@1
|
1097 |
|
alpar@1
|
1098 |
\begin{verbatim}
|
alpar@1
|
1099 |
void glp_delete_index(glp_prob *lp);
|
alpar@1
|
1100 |
\end{verbatim}
|
alpar@1
|
1101 |
|
alpar@1
|
1102 |
\subsubsection*{Description}
|
alpar@1
|
1103 |
|
alpar@1
|
1104 |
The routine \verb|glp_delete_index| deletes the name index previously
|
alpar@1
|
1105 |
created by the routine \verb|glp_create_index| and frees the memory
|
alpar@1
|
1106 |
allocated to this auxiliary data structure.
|
alpar@1
|
1107 |
|
alpar@1
|
1108 |
This routine can be called at any time. If the name index does not
|
alpar@1
|
1109 |
exist, the routine does nothing.
|
alpar@1
|
1110 |
|
alpar@1
|
1111 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
alpar@1
|
1112 |
|
alpar@1
|
1113 |
\newpage
|
alpar@1
|
1114 |
|
alpar@1
|
1115 |
\section{Problem scaling routines}
|
alpar@1
|
1116 |
|
alpar@1
|
1117 |
\subsection{Background}
|
alpar@1
|
1118 |
|
alpar@1
|
1119 |
In GLPK the {\it scaling} means a linear transformation applied to the
|
alpar@1
|
1120 |
constraint matrix to improve its numerical properties.\footnote{In many
|
alpar@1
|
1121 |
cases a proper scaling allows making the constraint matrix to be better
|
alpar@1
|
1122 |
conditioned, i.e. decreasing its condition number, that makes
|
alpar@1
|
1123 |
computations numerically more stable.}
|
alpar@1
|
1124 |
|
alpar@1
|
1125 |
The main equality is the following:
|
alpar@1
|
1126 |
$$\widetilde{A}=RAS,\eqno(2.1)$$
|
alpar@1
|
1127 |
where $A=(a_{ij})$ is the original constraint matrix, $R=(r_{ii})>0$ is
|
alpar@1
|
1128 |
a diagonal matrix used to scale rows (constraints), $S=(s_{jj})>0$ is a
|
alpar@1
|
1129 |
diagonal matrix used to scale columns (variables), $\widetilde{A}$ is
|
alpar@1
|
1130 |
the scaled constraint matrix.
|
alpar@1
|
1131 |
|
alpar@1
|
1132 |
From (2.1) it follows that in the {\it scaled} problem instance each
|
alpar@1
|
1133 |
original constraint coefficient $a_{ij}$ is replaced by corresponding
|
alpar@1
|
1134 |
scaled constraint coefficient:
|
alpar@1
|
1135 |
$$\widetilde{a}_{ij}=r_{ii}a_{ij}s_{jj}.\eqno(2.2)$$
|
alpar@1
|
1136 |
|
alpar@1
|
1137 |
Note that the scaling is performed internally and therefore
|
alpar@1
|
1138 |
transparently to the user. This means that on API level the user always
|
alpar@1
|
1139 |
deal with unscaled data.
|
alpar@1
|
1140 |
|
alpar@1
|
1141 |
Scale factors $r_{ii}$ and $s_{jj}$ can be set or changed at any time
|
alpar@1
|
1142 |
either directly by the application program in a problem specific way
|
alpar@1
|
1143 |
(with the routines \verb|glp_set_rii| and \verb|glp_set_sjj|), or by
|
alpar@1
|
1144 |
some API routines intended for automatic scaling.
|
alpar@1
|
1145 |
|
alpar@1
|
1146 |
\subsection{glp\_set\_rii---set (change) row scale factor}
|
alpar@1
|
1147 |
|
alpar@1
|
1148 |
\subsubsection*{Synopsis}
|
alpar@1
|
1149 |
|
alpar@1
|
1150 |
\begin{verbatim}
|
alpar@1
|
1151 |
void glp_set_rii(glp_prob *lp, int i, double rii);
|
alpar@1
|
1152 |
\end{verbatim}
|
alpar@1
|
1153 |
|
alpar@1
|
1154 |
\subsubsection*{Description}
|
alpar@1
|
1155 |
|
alpar@1
|
1156 |
The routine \verb|glp_set_rii| sets (changes) the scale factor $r_{ii}$
|
alpar@1
|
1157 |
for $i$-th row of the specified problem object.
|
alpar@1
|
1158 |
|
alpar@1
|
1159 |
\subsection{glp\_set\_sjj---set (change) column scale factor}
|
alpar@1
|
1160 |
|
alpar@1
|
1161 |
\subsubsection*{Synopsis}
|
alpar@1
|
1162 |
|
alpar@1
|
1163 |
\begin{verbatim}
|
alpar@1
|
1164 |
void glp_set_sjj(glp_prob *lp, int j, double sjj);
|
alpar@1
|
1165 |
\end{verbatim}
|
alpar@1
|
1166 |
|
alpar@1
|
1167 |
\subsubsection*{Description}
|
alpar@1
|
1168 |
|
alpar@1
|
1169 |
The routine \verb|glp_set_sjj| sets (changes) the scale factor $s_{jj}$
|
alpar@1
|
1170 |
for $j$-th column of the specified problem object.
|
alpar@1
|
1171 |
|
alpar@1
|
1172 |
\subsection{glp\_get\_rii---retrieve row scale factor}
|
alpar@1
|
1173 |
|
alpar@1
|
1174 |
\subsubsection*{Synopsis}
|
alpar@1
|
1175 |
|
alpar@1
|
1176 |
\begin{verbatim}
|
alpar@1
|
1177 |
double glp_get_rii(glp_prob *lp, int i);
|
alpar@1
|
1178 |
\end{verbatim}
|
alpar@1
|
1179 |
|
alpar@1
|
1180 |
\subsubsection*{Returns}
|
alpar@1
|
1181 |
|
alpar@1
|
1182 |
The routine \verb|glp_get_rii| returns current scale factor $r_{ii}$ for
|
alpar@1
|
1183 |
$i$-th row of the specified problem object.
|
alpar@1
|
1184 |
|
alpar@1
|
1185 |
\subsection{glp\_get\_sjj---retrieve column scale factor}
|
alpar@1
|
1186 |
|
alpar@1
|
1187 |
\subsubsection*{Synopsis}
|
alpar@1
|
1188 |
|
alpar@1
|
1189 |
\begin{verbatim}
|
alpar@1
|
1190 |
double glp_get_sjj(glp_prob *lp, int j);
|
alpar@1
|
1191 |
\end{verbatim}
|
alpar@1
|
1192 |
|
alpar@1
|
1193 |
\subsubsection*{Returns}
|
alpar@1
|
1194 |
|
alpar@1
|
1195 |
The routine \verb|glp_get_sjj| returns current scale factor $s_{jj}$ for
|
alpar@1
|
1196 |
$j$-th column of the specified problem object.
|
alpar@1
|
1197 |
|
alpar@1
|
1198 |
\subsection{glp\_scale\_prob---scale problem data}
|
alpar@1
|
1199 |
|
alpar@1
|
1200 |
\subsubsection*{Synopsis}
|
alpar@1
|
1201 |
|
alpar@1
|
1202 |
\begin{verbatim}
|
alpar@1
|
1203 |
void glp_scale_prob(glp_prob *lp, int flags);
|
alpar@1
|
1204 |
\end{verbatim}
|
alpar@1
|
1205 |
|
alpar@1
|
1206 |
\subsubsection*{Description}
|
alpar@1
|
1207 |
|
alpar@1
|
1208 |
The routine \verb|glp_scale_prob| performs automatic scaling of problem
|
alpar@1
|
1209 |
data for the specified problem object.
|
alpar@1
|
1210 |
|
alpar@1
|
1211 |
The parameter \verb|flags| specifies scaling options used by the
|
alpar@1
|
1212 |
routine. The options can be combined with the bitwise OR operator and
|
alpar@1
|
1213 |
may be the following:
|
alpar@1
|
1214 |
|
alpar@1
|
1215 |
\begin{tabular}{@{}ll}
|
alpar@1
|
1216 |
\verb|GLP_SF_GM| & perform geometric mean scaling;\\
|
alpar@1
|
1217 |
\verb|GLP_SF_EQ| & perform equilibration scaling;\\
|
alpar@1
|
1218 |
\verb|GLP_SF_2N| & round scale factors to nearest power of two;\\
|
alpar@1
|
1219 |
\verb|GLP_SF_SKIP| & skip scaling, if the problem is well scaled.\\
|
alpar@1
|
1220 |
\end{tabular}
|
alpar@1
|
1221 |
|
alpar@1
|
1222 |
The parameter \verb|flags| may be specified as \verb|GLP_SF_AUTO|, in
|
alpar@1
|
1223 |
which case the routine chooses the scaling options automatically.
|
alpar@1
|
1224 |
|
alpar@1
|
1225 |
\subsection{glp\_unscale\_prob---unscale problem data}
|
alpar@1
|
1226 |
|
alpar@1
|
1227 |
\subsubsection*{Synopsis}
|
alpar@1
|
1228 |
|
alpar@1
|
1229 |
\begin{verbatim}
|
alpar@1
|
1230 |
void glp_unscale_prob(glp_prob *lp);
|
alpar@1
|
1231 |
\end{verbatim}
|
alpar@1
|
1232 |
|
alpar@1
|
1233 |
The routine \verb|glp_unscale_prob| performs unscaling of problem data
|
alpar@1
|
1234 |
for the specified problem object.
|
alpar@1
|
1235 |
|
alpar@1
|
1236 |
``Unscaling'' means replacing the current scaling matrices $R$ and $S$
|
alpar@1
|
1237 |
by unity matrices that cancels the scaling effect.
|
alpar@1
|
1238 |
|
alpar@1
|
1239 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
alpar@1
|
1240 |
|
alpar@1
|
1241 |
\newpage
|
alpar@1
|
1242 |
|
alpar@1
|
1243 |
\section{LP basis constructing routines}
|
alpar@1
|
1244 |
|
alpar@1
|
1245 |
\subsection{Background}
|
alpar@1
|
1246 |
|
alpar@1
|
1247 |
To start the search the simplex method needs a valid initial basis. In
|
alpar@1
|
1248 |
GLPK the basis is completely defined by a set of {\it statuses} assigned
|
alpar@1
|
1249 |
to {\it all} (auxiliary and structural) variables, where the status may
|
alpar@1
|
1250 |
be one of the following:
|
alpar@1
|
1251 |
|
alpar@1
|
1252 |
\begin{tabular}{@{}ll}
|
alpar@1
|
1253 |
\verb|GLP_BS| & basic variable;\\
|
alpar@1
|
1254 |
\verb|GLP_NL| & non-basic variable having active lower bound;\\
|
alpar@1
|
1255 |
\verb|GLP_NU| & non-basic variable having active upper bound;\\
|
alpar@1
|
1256 |
\verb|GLP_NF| & non-basic free variable;\\
|
alpar@1
|
1257 |
\verb|GLP_NS| & non-basic fixed variable.\\
|
alpar@1
|
1258 |
\end{tabular}
|
alpar@1
|
1259 |
|
alpar@1
|
1260 |
The basis is {\it valid}, if the basis matrix, which is a matrix built
|
alpar@1
|
1261 |
of columns of the augmented constraint matrix $(I\:|-A)$ corresponding
|
alpar@1
|
1262 |
to basic variables, is non-singular. This, in particular, means that
|
alpar@1
|
1263 |
the number of basic variables must be the same as the number of rows in
|
alpar@1
|
1264 |
the problem object. (For more details see Section \ref{lpbasis}, page
|
alpar@1
|
1265 |
\pageref{lpbasis}.)
|
alpar@1
|
1266 |
|
alpar@1
|
1267 |
Any initial basis may be constructed (or restored) with the API
|
alpar@1
|
1268 |
routines \verb|glp_set_row_stat| and \verb|glp_set_col_stat| by
|
alpar@1
|
1269 |
assigning appropriate statuses to auxiliary and structural variables.
|
alpar@1
|
1270 |
Another way to construct an initial basis is to use API routines like
|
alpar@1
|
1271 |
\verb|glp_adv_basis|, which implement so called
|
alpar@1
|
1272 |
{\it crashing}.\footnote{This term is from early linear programming
|
alpar@1
|
1273 |
systems and means a heuristic to construct a valid initial basis.} Note
|
alpar@1
|
1274 |
that on normal exit the simplex solver remains the basis valid, so in
|
alpar@1
|
1275 |
case of reoptimization there is no need to construct an initial basis
|
alpar@1
|
1276 |
from scratch.
|
alpar@1
|
1277 |
|
alpar@1
|
1278 |
\subsection{glp\_set\_row\_stat---set (change) row status}
|
alpar@1
|
1279 |
|
alpar@1
|
1280 |
\subsubsection*{Synopsis}
|
alpar@1
|
1281 |
|
alpar@1
|
1282 |
\begin{verbatim}
|
alpar@1
|
1283 |
void glp_set_row_stat(glp_prob *lp, int i, int stat);
|
alpar@1
|
1284 |
\end{verbatim}
|
alpar@1
|
1285 |
|
alpar@1
|
1286 |
\subsubsection*{Description}
|
alpar@1
|
1287 |
|
alpar@1
|
1288 |
The routine \verb|glp_set_row_stat| sets (changes) the current status
|
alpar@1
|
1289 |
of \verb|i|-th row (auxiliary variable) as specified by the parameter
|
alpar@1
|
1290 |
\verb|stat|:
|
alpar@1
|
1291 |
|
alpar@1
|
1292 |
\begin{tabular}{@{}lp{104.2mm}@{}}
|
alpar@1
|
1293 |
\verb|GLP_BS| & make the row basic (make the constraint inactive); \\
|
alpar@1
|
1294 |
\verb|GLP_NL| & make the row non-basic (make the constraint active); \\
|
alpar@1
|
1295 |
\end{tabular}
|
alpar@1
|
1296 |
|
alpar@1
|
1297 |
\newpage
|
alpar@1
|
1298 |
|
alpar@1
|
1299 |
\begin{tabular}{@{}lp{104.2mm}@{}}
|
alpar@1
|
1300 |
\verb|GLP_NU| & make the row non-basic and set it to the upper bound;
|
alpar@1
|
1301 |
if the row is not double-bounded, this status is equivalent to
|
alpar@1
|
1302 |
\verb|GLP_NL| (only in the case of this routine); \\
|
alpar@1
|
1303 |
\verb|GLP_NF| & the same as \verb|GLP_NL| (only in the case of this
|
alpar@1
|
1304 |
routine); \\
|
alpar@1
|
1305 |
\verb|GLP_NS| & the same as \verb|GLP_NL| (only in the case of this
|
alpar@1
|
1306 |
routine). \\
|
alpar@1
|
1307 |
\end{tabular}
|
alpar@1
|
1308 |
|
alpar@1
|
1309 |
\subsection{glp\_set\_col\_stat---set (change) column status}
|
alpar@1
|
1310 |
|
alpar@1
|
1311 |
\subsubsection*{Synopsis}
|
alpar@1
|
1312 |
|
alpar@1
|
1313 |
\begin{verbatim}
|
alpar@1
|
1314 |
void glp_set_col_stat(glp_prob *lp, int j, int stat);
|
alpar@1
|
1315 |
\end{verbatim}
|
alpar@1
|
1316 |
|
alpar@1
|
1317 |
\subsubsection*{Description}
|
alpar@1
|
1318 |
|
alpar@1
|
1319 |
The routine \verb|glp_set_col_stat sets| (changes) the current status
|
alpar@1
|
1320 |
of \verb|j|-th column (structural variable) as specified by the
|
alpar@1
|
1321 |
parameter \verb|stat|:
|
alpar@1
|
1322 |
|
alpar@1
|
1323 |
\begin{tabular}{@{}lp{104.2mm}@{}}
|
alpar@1
|
1324 |
\verb|GLP_BS| & make the column basic; \\
|
alpar@1
|
1325 |
\verb|GLP_NL| & make the column non-basic; \\
|
alpar@1
|
1326 |
\verb|GLP_NU| & make the column non-basic and set it to the upper
|
alpar@1
|
1327 |
bound; if the column is not double-bounded, this status is equivalent
|
alpar@1
|
1328 |
to \verb|GLP_NL| (only in the case of this routine); \\
|
alpar@1
|
1329 |
\verb|GLP_NF| & the same as \verb|GLP_NL| (only in the case of this
|
alpar@1
|
1330 |
routine); \\
|
alpar@1
|
1331 |
\verb|GLP_NS| & the same as \verb|GLP_NL| (only in the case of this
|
alpar@1
|
1332 |
routine).
|
alpar@1
|
1333 |
\end{tabular}
|
alpar@1
|
1334 |
|
alpar@1
|
1335 |
\subsection{glp\_std\_basis---construct standard initial LP basis}
|
alpar@1
|
1336 |
|
alpar@1
|
1337 |
\subsubsection*{Synopsis}
|
alpar@1
|
1338 |
|
alpar@1
|
1339 |
\begin{verbatim}
|
alpar@1
|
1340 |
void glp_std_basis(glp_prob *lp);
|
alpar@1
|
1341 |
\end{verbatim}
|
alpar@1
|
1342 |
|
alpar@1
|
1343 |
\subsubsection*{Description}
|
alpar@1
|
1344 |
|
alpar@1
|
1345 |
The routine \verb|glp_std_basis| constructs the ``standard'' (trivial)
|
alpar@1
|
1346 |
initial LP basis for the specified problem object.
|
alpar@1
|
1347 |
|
alpar@1
|
1348 |
In the ``standard'' LP basis all auxiliary variables (rows) are basic,
|
alpar@1
|
1349 |
and all structural variables (columns) are non-basic (so the
|
alpar@1
|
1350 |
corresponding basis matrix is unity).
|
alpar@1
|
1351 |
|
alpar@1
|
1352 |
\newpage
|
alpar@1
|
1353 |
|
alpar@1
|
1354 |
\subsection{glp\_adv\_basis---construct advanced initial LP basis}
|
alpar@1
|
1355 |
|
alpar@1
|
1356 |
\subsubsection*{Synopsis}
|
alpar@1
|
1357 |
|
alpar@1
|
1358 |
\begin{verbatim}
|
alpar@1
|
1359 |
void glp_adv_basis(glp_prob *lp, int flags);
|
alpar@1
|
1360 |
\end{verbatim}
|
alpar@1
|
1361 |
|
alpar@1
|
1362 |
\subsubsection*{Description}
|
alpar@1
|
1363 |
|
alpar@1
|
1364 |
The routine \verb|glp_adv_basis| constructs an advanced initial LP
|
alpar@1
|
1365 |
basis for the specified problem object.
|
alpar@1
|
1366 |
|
alpar@1
|
1367 |
The parameter \verb|flags| is reserved for use in the future and must
|
alpar@1
|
1368 |
be specified as zero.
|
alpar@1
|
1369 |
|
alpar@1
|
1370 |
In order to construct the advanced initial LP basis the routine does
|
alpar@1
|
1371 |
the following:
|
alpar@1
|
1372 |
|
alpar@1
|
1373 |
1) includes in the basis all non-fixed auxiliary variables;
|
alpar@1
|
1374 |
|
alpar@1
|
1375 |
2) includes in the basis as many non-fixed structural variables as
|
alpar@1
|
1376 |
possible keeping the triangular form of the basis matrix;
|
alpar@1
|
1377 |
|
alpar@1
|
1378 |
3) includes in the basis appropriate (fixed) auxiliary variables to
|
alpar@1
|
1379 |
complete the basis.
|
alpar@1
|
1380 |
|
alpar@1
|
1381 |
As a result the initial LP basis has as few fixed variables as possible
|
alpar@1
|
1382 |
and the corresponding basis matrix is triangular.
|
alpar@1
|
1383 |
|
alpar@1
|
1384 |
\subsection{glp\_cpx\_basis---construct Bixby's initial LP basis}
|
alpar@1
|
1385 |
|
alpar@1
|
1386 |
\subsubsection*{Synopsis}
|
alpar@1
|
1387 |
|
alpar@1
|
1388 |
\begin{verbatim}
|
alpar@1
|
1389 |
void glp_cpx_basis(glp_prob *lp);
|
alpar@1
|
1390 |
\end{verbatim}
|
alpar@1
|
1391 |
|
alpar@1
|
1392 |
\subsubsection*{Description}
|
alpar@1
|
1393 |
|
alpar@1
|
1394 |
The routine \verb|glp_cpx_basis| constructs an initial basis for the
|
alpar@1
|
1395 |
specified problem object with the algorithm proposed by
|
alpar@1
|
1396 |
R.~Bixby.\footnote{Robert E. Bixby, ``Implementing the Simplex Method:
|
alpar@1
|
1397 |
The Initial Basis.'' ORSA Journal on Computing, Vol. 4, No. 3, 1992,
|
alpar@1
|
1398 |
pp. 267-84.}
|
alpar@1
|
1399 |
|
alpar@1
|
1400 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
alpar@1
|
1401 |
|
alpar@1
|
1402 |
\newpage
|
alpar@1
|
1403 |
|
alpar@1
|
1404 |
\section{Simplex method routines}
|
alpar@1
|
1405 |
|
alpar@1
|
1406 |
The {\it simplex method} is a well known efficient numerical procedure
|
alpar@1
|
1407 |
to solve LP problems.
|
alpar@1
|
1408 |
|
alpar@1
|
1409 |
On each iteration the simplex method transforms the original system of
|
alpar@1
|
1410 |
equaility constraints (1.2) resolving them through different sets of
|
alpar@1
|
1411 |
variables to an equivalent system called {\it the simplex table} (or
|
alpar@1
|
1412 |
sometimes {\it the simplex tableau}), which has the following form:
|
alpar@1
|
1413 |
$$
|
alpar@1
|
1414 |
\begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}r}
|
alpar@1
|
1415 |
z&=&d_1(x_N)_1&+&d_2(x_N)_2&+ \dots +&d_n(x_N)_n \\
|
alpar@1
|
1416 |
(x_B)_1&=&\xi_{11}(x_N)_1& +& \xi_{12}(x_N)_2& + \dots +&
|
alpar@1
|
1417 |
\xi_{1n}(x_N)_n \\
|
alpar@1
|
1418 |
(x_B)_2&=& \xi_{21}(x_N)_1& +& \xi_{22}(x_N)_2& + \dots +&
|
alpar@1
|
1419 |
\xi_{2n}(x_N)_n \\
|
alpar@1
|
1420 |
\multicolumn{7}{c}
|
alpar@1
|
1421 |
{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .} \\
|
alpar@1
|
1422 |
(x_B)_m&=&\xi_{m1}(x_N)_1& +& \xi_{m2}(x_N)_2& + \dots +&
|
alpar@1
|
1423 |
\xi_{mn}(x_N)_n \\
|
alpar@1
|
1424 |
\end{array} \eqno (2.3)
|
alpar@1
|
1425 |
$$
|
alpar@1
|
1426 |
where: $(x_B)_1, (x_B)_2, \dots, (x_B)_m$ are basic variables;
|
alpar@1
|
1427 |
$(x_N)_1, (x_N)_2, \dots, (x_N)_n$ are non-basic variables;
|
alpar@1
|
1428 |
$d_1, d_2, \dots, d_n$ are reduced costs;
|
alpar@1
|
1429 |
$\xi_{11}, \xi_{12}, \dots, \xi_{mn}$ are coefficients of the
|
alpar@1
|
1430 |
simplex table. (May note that the original LP problem (1.1)---(1.3) also
|
alpar@1
|
1431 |
has the form of a simplex table, where all equalities are resolved
|
alpar@1
|
1432 |
through auxiliary variables.)
|
alpar@1
|
1433 |
|
alpar@1
|
1434 |
From the linear programming theory it is known that if an optimal
|
alpar@1
|
1435 |
solution of the LP problem (1.1)---(1.3) exists, it can always be
|
alpar@1
|
1436 |
written in the form (2.3), where non-basic variables are set on their
|
alpar@1
|
1437 |
bounds while values of the objective function and basic variables are
|
alpar@1
|
1438 |
determined by the corresponding equalities of the simplex table.
|
alpar@1
|
1439 |
|
alpar@1
|
1440 |
A set of values of all basic and non-basic variables determined by the
|
alpar@1
|
1441 |
simplex table is called {\it basic solution}. If all basic variables are
|
alpar@1
|
1442 |
within their bounds, the basic solution is called {\it (primal)
|
alpar@1
|
1443 |
feasible}, otherwise it is called {\it (primal) infeasible}. A feasible
|
alpar@1
|
1444 |
basic solution, which provides a smallest (in case of minimization) or
|
alpar@1
|
1445 |
a largest (in case of maximization) value of the objective function is
|
alpar@1
|
1446 |
called {\it optimal}. Therefore, for solving LP problem the simplex
|
alpar@1
|
1447 |
method tries to find its optimal basic solution.
|
alpar@1
|
1448 |
|
alpar@1
|
1449 |
Primal feasibility of some basic solution may be stated by simple
|
alpar@1
|
1450 |
checking if all basic variables are within their bounds. Basic solution
|
alpar@1
|
1451 |
is optimal if additionally the following optimality conditions are
|
alpar@1
|
1452 |
satisfied for all non-basic variables:
|
alpar@1
|
1453 |
\begin{center}
|
alpar@1
|
1454 |
\begin{tabular}{lcc}
|
alpar@1
|
1455 |
Status of $(x_N)_j$ & Minimization & Maximization \\
|
alpar@1
|
1456 |
\hline
|
alpar@1
|
1457 |
$(x_N)_j$ is free & $d_j = 0$ & $d_j = 0$ \\
|
alpar@1
|
1458 |
$(x_N)_j$ is on its lower bound & $d_j \geq 0$ & $d_j \leq 0$ \\
|
alpar@1
|
1459 |
$(x_N)_j$ is on its upper bound & $d_j \leq 0$ & $d_j \geq 0$ \\
|
alpar@1
|
1460 |
\end{tabular}
|
alpar@1
|
1461 |
\end{center}
|
alpar@1
|
1462 |
In other words, basic solution is optimal if there is no non-basic
|
alpar@1
|
1463 |
variable, which changing in the feasible direction (i.e. increasing if
|
alpar@1
|
1464 |
it is free or on its lower bound, or decreasing if it is free or on its
|
alpar@1
|
1465 |
upper bound) can improve (i.e. decrease in case of minimization or
|
alpar@1
|
1466 |
increase in case of maximization) the objective function.
|
alpar@1
|
1467 |
|
alpar@1
|
1468 |
If all non-basic variables satisfy to the optimality conditions shown
|
alpar@1
|
1469 |
above (independently on whether basic variables are within their bounds
|
alpar@1
|
1470 |
or not), the basic solution is called {\it dual feasible}, otherwise it
|
alpar@1
|
1471 |
is called {\it dual infeasible}.
|
alpar@1
|
1472 |
|
alpar@1
|
1473 |
It may happen that some LP problem has no primal feasible solution due
|
alpar@1
|
1474 |
to incorrect formulation---this means that its constraints conflict
|
alpar@1
|
1475 |
with each other. It also may happen that some LP problem has unbounded
|
alpar@1
|
1476 |
solution again due to incorrect formulation---this means that some
|
alpar@1
|
1477 |
non-basic variable can improve the objective function, i.e. the
|
alpar@1
|
1478 |
optimality conditions are violated, and at the same time this variable
|
alpar@1
|
1479 |
can infinitely change in the feasible direction meeting no resistance
|
alpar@1
|
1480 |
from basic variables. (May note that in the latter case the LP problem
|
alpar@1
|
1481 |
has no dual feasible solution.)
|
alpar@1
|
1482 |
|
alpar@1
|
1483 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
alpar@1
|
1484 |
|
alpar@1
|
1485 |
\subsection{glp\_simplex---solve LP problem with the primal or dual
|
alpar@1
|
1486 |
simplex method}
|
alpar@1
|
1487 |
|
alpar@1
|
1488 |
\subsubsection*{Synopsis}
|
alpar@1
|
1489 |
|
alpar@1
|
1490 |
\begin{verbatim}
|
alpar@1
|
1491 |
int glp_simplex(glp_prob *lp, const glp_smcp *parm);
|
alpar@1
|
1492 |
\end{verbatim}
|
alpar@1
|
1493 |
|
alpar@1
|
1494 |
\subsubsection*{Description}
|
alpar@1
|
1495 |
|
alpar@1
|
1496 |
The routine \verb|glp_simplex| is a driver to the LP solver based on
|
alpar@1
|
1497 |
the simplex method. This routine retrieves problem data from the
|
alpar@1
|
1498 |
specified problem object, calls the solver to solve the problem
|
alpar@1
|
1499 |
instance, and stores results of computations back into the problem
|
alpar@1
|
1500 |
object.
|
alpar@1
|
1501 |
|
alpar@1
|
1502 |
The simplex solver has a set of control parameters. Values of the
|
alpar@1
|
1503 |
control parameters can be passed in the structure \verb|glp_smcp|,
|
alpar@1
|
1504 |
which the parameter \verb|parm| points to. For detailed description of
|
alpar@1
|
1505 |
this structure see paragraph ``Control parameters'' below.
|
alpar@1
|
1506 |
Before specifying some control parameters the application program
|
alpar@1
|
1507 |
should initialize the structure \verb|glp_smcp| by default values of
|
alpar@1
|
1508 |
all control parameters using the routine \verb|glp_init_smcp| (see the
|
alpar@1
|
1509 |
next subsection). This is needed for backward compatibility, because in
|
alpar@1
|
1510 |
the future there may appear new members in the structure
|
alpar@1
|
1511 |
\verb|glp_smcp|.
|
alpar@1
|
1512 |
|
alpar@1
|
1513 |
The parameter \verb|parm| can be specified as \verb|NULL|, in which
|
alpar@1
|
1514 |
case the solver uses default settings.
|
alpar@1
|
1515 |
|
alpar@1
|
1516 |
\subsubsection*{Returns}
|
alpar@1
|
1517 |
|
alpar@1
|
1518 |
\def\arraystretch{1}
|
alpar@1
|
1519 |
|
alpar@1
|
1520 |
\begin{tabular}{@{}p{25mm}p{97.3mm}@{}}
|
alpar@1
|
1521 |
0 & The LP problem instance has been successfully solved. (This code
|
alpar@1
|
1522 |
does {\it not} necessarily mean that the solver has found optimal
|
alpar@1
|
1523 |
solution. It only means that the solution process was successful.) \\
|
alpar@1
|
1524 |
\verb|GLP_EBADB| & Unable to start the search, because the initial basis
|
alpar@1
|
1525 |
specified in the problem object is invalid---the number of basic
|
alpar@1
|
1526 |
(auxiliary and structural) variables is not the same as the number of
|
alpar@1
|
1527 |
rows in the problem object.\\
|
alpar@1
|
1528 |
\verb|GLP_ESING| & Unable to start the search, because the basis matrix
|
alpar@1
|
1529 |
corresponding to the initial basis is singular within the working
|
alpar@1
|
1530 |
precision.\\
|
alpar@1
|
1531 |
\verb|GLP_ECOND| & Unable to start the search, because the basis matrix
|
alpar@1
|
1532 |
corresponding to the initial basis is ill-conditioned, i.e. its
|
alpar@1
|
1533 |
condition number is too large.\\
|
alpar@1
|
1534 |
\verb|GLP_EBOUND| & Unable to start the search, because some
|
alpar@1
|
1535 |
double-bounded (auxiliary or structural) variables have incorrect
|
alpar@1
|
1536 |
bounds.\\
|
alpar@1
|
1537 |
\verb|GLP_EFAIL| & The search was prematurely terminated due to the
|
alpar@1
|
1538 |
solver failure.\\
|
alpar@1
|
1539 |
\verb|GLP_EOBJLL| & The search was prematurely terminated, because the
|
alpar@1
|
1540 |
objective function being maximized has reached its lower limit and
|
alpar@1
|
1541 |
continues decreasing (the dual simplex only).\\
|
alpar@1
|
1542 |
\verb|GLP_EOBJUL| & The search was prematurely terminated, because the
|
alpar@1
|
1543 |
objective function being minimized has reached its upper limit and
|
alpar@1
|
1544 |
continues increasing (the dual simplex only).\\
|
alpar@1
|
1545 |
\verb|GLP_EITLIM| & The search was prematurely terminated, because the
|
alpar@1
|
1546 |
simplex iteration limit has been exceeded.\\
|
alpar@1
|
1547 |
\verb|GLP_ETMLIM| & The search was prematurely terminated, because the
|
alpar@1
|
1548 |
time limit has been exceeded.\\
|
alpar@1
|
1549 |
\verb|GLP_ENOPFS| & The LP problem instance has no primal feasible
|
alpar@1
|
1550 |
solution (only if the LP presolver is used).\\
|
alpar@1
|
1551 |
\verb|GLP_ENODFS| & The LP problem instance has no dual feasible
|
alpar@1
|
1552 |
solution (only if the LP presolver is used).\\
|
alpar@1
|
1553 |
\end{tabular}
|
alpar@1
|
1554 |
|
alpar@1
|
1555 |
\subsubsection*{Built-in LP presolver}
|
alpar@1
|
1556 |
|
alpar@1
|
1557 |
The simplex solver has {\it built-in LP presolver}. It is a subprogram
|
alpar@1
|
1558 |
that transforms the original LP problem specified in the problem object
|
alpar@1
|
1559 |
to an equivalent LP problem, which may be easier for solving with the
|
alpar@1
|
1560 |
simplex method than the original one. This is attained mainly due to
|
alpar@1
|
1561 |
reducing the problem size and improving its numeric properties (for
|
alpar@1
|
1562 |
example, by removing some inactive constraints or by fixing some
|
alpar@1
|
1563 |
non-basic variables). Once the transformed LP problem has been solved,
|
alpar@1
|
1564 |
the presolver transforms its basic solution back to the corresponding
|
alpar@1
|
1565 |
basic solution of the original problem.
|
alpar@1
|
1566 |
|
alpar@1
|
1567 |
Presolving is an optional feature of the routine \verb|glp_simplex|,
|
alpar@1
|
1568 |
and by default it is disabled. In order to enable the LP presolver the
|
alpar@1
|
1569 |
control parameter \verb|presolve| should be set to \verb|GLP_ON| (see
|
alpar@1
|
1570 |
paragraph ``Control parameters'' below). Presolving may be used when
|
alpar@1
|
1571 |
the problem instance is solved for the first time. However, on
|
alpar@1
|
1572 |
performing re-optimization the presolver should be disabled.
|
alpar@1
|
1573 |
|
alpar@1
|
1574 |
The presolving procedure is transparent to the API user in the sense
|
alpar@1
|
1575 |
that all necessary processing is performed internally, and a basic
|
alpar@1
|
1576 |
solution of the original problem recovered by the presolver is the same
|
alpar@1
|
1577 |
as if it were computed directly, i.e. without presolving.
|
alpar@1
|
1578 |
|
alpar@1
|
1579 |
Note that the presolver is able to recover only optimal solutions. If
|
alpar@1
|
1580 |
a computed solution is infeasible or non-optimal, the corresponding
|
alpar@1
|
1581 |
solution of the original problem cannot be recovered and therefore
|
alpar@1
|
1582 |
remains undefined. If you need to know a basic solution even if it is
|
alpar@1
|
1583 |
infeasible or non-optimal, the presolver should be disabled.
|
alpar@1
|
1584 |
|
alpar@1
|
1585 |
\subsubsection*{Terminal output}
|
alpar@1
|
1586 |
|
alpar@1
|
1587 |
Solving large problem instances may take a long time, so the solver
|
alpar@1
|
1588 |
reports some information about the current basic solution, which is sent
|
alpar@1
|
1589 |
to the terminal. This information has the following format:
|
alpar@1
|
1590 |
|
alpar@1
|
1591 |
\begin{verbatim}
|
alpar@1
|
1592 |
nnn: obj = xxx infeas = yyy (ddd)
|
alpar@1
|
1593 |
\end{verbatim}
|
alpar@1
|
1594 |
|
alpar@1
|
1595 |
\noindent
|
alpar@1
|
1596 |
where: `\verb|nnn|' is the iteration number, `\verb|xxx|' is the
|
alpar@1
|
1597 |
current value of the objective function (it is is unscaled and has
|
alpar@1
|
1598 |
correct sign); `\verb|yyy|' is the current sum of primal or dual
|
alpar@1
|
1599 |
infeasibilities (it is scaled and therefore may be used only for visual
|
alpar@1
|
1600 |
estimating), `\verb|ddd|' is the current number of fixed basic
|
alpar@1
|
1601 |
variables.
|
alpar@1
|
1602 |
|
alpar@1
|
1603 |
The symbol preceding the iteration number indicates which phase of the
|
alpar@1
|
1604 |
simplex method is in effect:
|
alpar@1
|
1605 |
|
alpar@1
|
1606 |
{\it Blank} means that the solver is searching for primal feasible
|
alpar@1
|
1607 |
solution using the primal simplex or for dual feasible solution using
|
alpar@1
|
1608 |
the dual simplex;
|
alpar@1
|
1609 |
|
alpar@1
|
1610 |
{\it Asterisk} (\verb|*|) means that the solver is searching for
|
alpar@1
|
1611 |
optimal solution using the primal simplex;
|
alpar@1
|
1612 |
|
alpar@1
|
1613 |
{\it Vertical dash} (\verb/|/) means that the solver is searching for
|
alpar@1
|
1614 |
optimal solution using the dual simplex.
|
alpar@1
|
1615 |
|
alpar@1
|
1616 |
\subsubsection*{Control parameters}
|
alpar@1
|
1617 |
|
alpar@1
|
1618 |
This paragraph describes all control parameters currently used in the
|
alpar@1
|
1619 |
simplex solver. Symbolic names of control parameters are names of
|
alpar@1
|
1620 |
corresponding members in the structure \verb|glp_smcp|.
|
alpar@1
|
1621 |
|
alpar@1
|
1622 |
\medskip
|
alpar@1
|
1623 |
|
alpar@1
|
1624 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
1625 |
\multicolumn{2}{@{}l}{{\tt int msg\_lev} (default: {\tt GLP\_MSG\_ALL})}
|
alpar@1
|
1626 |
\\
|
alpar@1
|
1627 |
&Message level for terminal output:\\
|
alpar@1
|
1628 |
&\verb|GLP_MSG_OFF|---no output;\\
|
alpar@1
|
1629 |
&\verb|GLP_MSG_ERR|---error and warning messages only;\\
|
alpar@1
|
1630 |
&\verb|GLP_MSG_ON |---normal output;\\
|
alpar@1
|
1631 |
&\verb|GLP_MSG_ALL|---full output (including informational messages).
|
alpar@1
|
1632 |
\\
|
alpar@1
|
1633 |
\end{tabular}
|
alpar@1
|
1634 |
|
alpar@1
|
1635 |
\medskip
|
alpar@1
|
1636 |
|
alpar@1
|
1637 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
1638 |
\multicolumn{2}{@{}l}{{\tt int meth} (default: {\tt GLP\_PRIMAL})}
|
alpar@1
|
1639 |
\\
|
alpar@1
|
1640 |
&Simplex method option:\\
|
alpar@1
|
1641 |
&\verb|GLP_PRIMAL|---use two-phase primal simplex;\\
|
alpar@1
|
1642 |
&\verb|GLP_DUAL |---use two-phase dual simplex;\\
|
alpar@1
|
1643 |
&\verb|GLP_DUALP |---use two-phase dual simplex, and if it fails,
|
alpar@1
|
1644 |
switch to the\\
|
alpar@1
|
1645 |
&\verb| |$\:$ primal simplex.\\
|
alpar@1
|
1646 |
\end{tabular}
|
alpar@1
|
1647 |
|
alpar@1
|
1648 |
\medskip
|
alpar@1
|
1649 |
|
alpar@1
|
1650 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
1651 |
\multicolumn{2}{@{}l}{{\tt int pricing} (default: {\tt GLP\_PT\_PSE})}
|
alpar@1
|
1652 |
\\
|
alpar@1
|
1653 |
&Pricing technique:\\
|
alpar@1
|
1654 |
&\verb|GLP_PT_STD|---standard (textbook);\\
|
alpar@1
|
1655 |
&\verb|GLP_PT_PSE|---projected steepest edge.\\
|
alpar@1
|
1656 |
\end{tabular}
|
alpar@1
|
1657 |
|
alpar@1
|
1658 |
\medskip
|
alpar@1
|
1659 |
|
alpar@1
|
1660 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
1661 |
\multicolumn{2}{@{}l}{{\tt int r\_test} (default: {\tt GLP\_RT\_HAR})}
|
alpar@1
|
1662 |
\\
|
alpar@1
|
1663 |
&Ratio test technique:\\
|
alpar@1
|
1664 |
&\verb|GLP_RT_STD|---standard (textbook);\\
|
alpar@1
|
1665 |
&\verb|GLP_RT_HAR|---Harris' two-pass ratio test.\\
|
alpar@1
|
1666 |
\end{tabular}
|
alpar@1
|
1667 |
|
alpar@1
|
1668 |
\medskip
|
alpar@1
|
1669 |
|
alpar@1
|
1670 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
1671 |
\multicolumn{2}{@{}l}{{\tt double tol\_bnd} (default: {\tt 1e-7})}
|
alpar@1
|
1672 |
\\
|
alpar@1
|
1673 |
&Tolerance used to check if the basic solution is primal feasible.
|
alpar@1
|
1674 |
(Do not change this parameter without detailed understanding its
|
alpar@1
|
1675 |
purpose.)\\
|
alpar@1
|
1676 |
\end{tabular}
|
alpar@1
|
1677 |
|
alpar@1
|
1678 |
\medskip
|
alpar@1
|
1679 |
|
alpar@1
|
1680 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
1681 |
\multicolumn{2}{@{}l}{{\tt double tol\_dj} (default: {\tt 1e-7})}
|
alpar@1
|
1682 |
\\
|
alpar@1
|
1683 |
&Tolerance used to check if the basic solution is dual feasible.
|
alpar@1
|
1684 |
(Do not change this parameter without detailed understanding its
|
alpar@1
|
1685 |
purpose.)\\
|
alpar@1
|
1686 |
\end{tabular}
|
alpar@1
|
1687 |
|
alpar@1
|
1688 |
\medskip
|
alpar@1
|
1689 |
|
alpar@1
|
1690 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
1691 |
\multicolumn{2}{@{}l}{{\tt double tol\_piv} (default: {\tt 1e-10})}
|
alpar@1
|
1692 |
\\
|
alpar@1
|
1693 |
&Tolerance used to choose eligble pivotal elements of the simplex table.
|
alpar@1
|
1694 |
(Do not change this parameter without detailed understanding its
|
alpar@1
|
1695 |
purpose.)\\
|
alpar@1
|
1696 |
\end{tabular}
|
alpar@1
|
1697 |
|
alpar@1
|
1698 |
\medskip
|
alpar@1
|
1699 |
|
alpar@1
|
1700 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
1701 |
\multicolumn{2}{@{}l}{{\tt double obj\_ll} (default: {\tt -DBL\_MAX})}
|
alpar@1
|
1702 |
\\
|
alpar@1
|
1703 |
&Lower limit of the objective function. If the objective function
|
alpar@1
|
1704 |
reaches this limit and continues decreasing, the solver terminates the
|
alpar@1
|
1705 |
search. (Used in the dual simplex only.)\\
|
alpar@1
|
1706 |
\end{tabular}
|
alpar@1
|
1707 |
|
alpar@1
|
1708 |
\medskip
|
alpar@1
|
1709 |
|
alpar@1
|
1710 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
1711 |
\multicolumn{2}{@{}l}{{\tt double obj\_ul} (default: {\tt +DBL\_MAX})}
|
alpar@1
|
1712 |
\\
|
alpar@1
|
1713 |
&Upper limit of the objective function. If the objective function
|
alpar@1
|
1714 |
reaches this limit and continues increasing, the solver terminates the
|
alpar@1
|
1715 |
search. (Used in the dual simplex only.)\\
|
alpar@1
|
1716 |
\end{tabular}
|
alpar@1
|
1717 |
|
alpar@1
|
1718 |
\medskip
|
alpar@1
|
1719 |
|
alpar@1
|
1720 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
1721 |
\multicolumn{2}{@{}l}{{\tt int it\_lim} (default: {\tt INT\_MAX})}
|
alpar@1
|
1722 |
\\
|
alpar@1
|
1723 |
&Simplex iteration limit.\\
|
alpar@1
|
1724 |
\end{tabular}
|
alpar@1
|
1725 |
|
alpar@1
|
1726 |
\medskip
|
alpar@1
|
1727 |
|
alpar@1
|
1728 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
1729 |
\multicolumn{2}{@{}l}{{\tt int tm\_lim} (default: {\tt INT\_MAX})}
|
alpar@1
|
1730 |
\\
|
alpar@1
|
1731 |
&Searching time limit, in milliseconds.\\
|
alpar@1
|
1732 |
\end{tabular}
|
alpar@1
|
1733 |
|
alpar@1
|
1734 |
\medskip
|
alpar@1
|
1735 |
|
alpar@1
|
1736 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
1737 |
\multicolumn{2}{@{}l}{{\tt int out\_frq} (default: {\tt 500})}
|
alpar@1
|
1738 |
\\
|
alpar@1
|
1739 |
&Output frequency, in iterations. This parameter specifies how
|
alpar@1
|
1740 |
frequently the solver sends information about the solution process to
|
alpar@1
|
1741 |
the terminal.\\
|
alpar@1
|
1742 |
\end{tabular}
|
alpar@1
|
1743 |
|
alpar@1
|
1744 |
\medskip
|
alpar@1
|
1745 |
|
alpar@1
|
1746 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
1747 |
\multicolumn{2}{@{}l}{{\tt int out\_dly} (default: {\tt 0})}
|
alpar@1
|
1748 |
\\
|
alpar@1
|
1749 |
&Output delay, in milliseconds. This parameter specifies how long the
|
alpar@1
|
1750 |
solver should delay sending information about the solution process to
|
alpar@1
|
1751 |
the terminal.\\
|
alpar@1
|
1752 |
\end{tabular}
|
alpar@1
|
1753 |
|
alpar@1
|
1754 |
\medskip
|
alpar@1
|
1755 |
|
alpar@1
|
1756 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
1757 |
\multicolumn{2}{@{}l}{{\tt int presolve} (default: {\tt GLP\_OFF})}
|
alpar@1
|
1758 |
\\
|
alpar@1
|
1759 |
&LP presolver option:\\
|
alpar@1
|
1760 |
&\verb|GLP_ON |---enable using the LP presolver;\\
|
alpar@1
|
1761 |
&\verb|GLP_OFF|---disable using the LP presolver.\\
|
alpar@1
|
1762 |
\end{tabular}
|
alpar@1
|
1763 |
|
alpar@1
|
1764 |
\subsubsection*{Example 1}
|
alpar@1
|
1765 |
|
alpar@1
|
1766 |
The following main program reads LP problem instance in fixed MPS
|
alpar@1
|
1767 |
format from file \verb|25fv47.mps|,\footnote{This instance in fixed MPS
|
alpar@1
|
1768 |
format can be found in the Netlib LP collection; see
|
alpar@1
|
1769 |
{\tt ftp://ftp.netlib.org/lp/data/}.} constructs an advanced initial
|
alpar@1
|
1770 |
basis, solves the instance with the primal simplex method (by default),
|
alpar@1
|
1771 |
and writes the solution to file \verb|25fv47.txt|.
|
alpar@1
|
1772 |
|
alpar@1
|
1773 |
\newpage
|
alpar@1
|
1774 |
|
alpar@1
|
1775 |
\begin{footnotesize}
|
alpar@1
|
1776 |
\begin{verbatim}
|
alpar@1
|
1777 |
/* spxsamp1.c */
|
alpar@1
|
1778 |
|
alpar@1
|
1779 |
#include <stdio.h>
|
alpar@1
|
1780 |
#include <stdlib.h>
|
alpar@1
|
1781 |
#include <glpk.h>
|
alpar@1
|
1782 |
|
alpar@1
|
1783 |
int main(void)
|
alpar@1
|
1784 |
{ glp_prob *P;
|
alpar@1
|
1785 |
P = glp_create_prob();
|
alpar@1
|
1786 |
glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps");
|
alpar@1
|
1787 |
glp_adv_basis(P, 0);
|
alpar@1
|
1788 |
glp_simplex(P, NULL);
|
alpar@1
|
1789 |
glp_print_sol(P, "25fv47.txt");
|
alpar@1
|
1790 |
glp_delete_prob(P);
|
alpar@1
|
1791 |
return 0;
|
alpar@1
|
1792 |
}
|
alpar@1
|
1793 |
|
alpar@1
|
1794 |
/* eof */
|
alpar@1
|
1795 |
\end{verbatim}
|
alpar@1
|
1796 |
\end{footnotesize}
|
alpar@1
|
1797 |
|
alpar@1
|
1798 |
\noindent
|
alpar@1
|
1799 |
Below here is shown the terminal output from this example program.
|
alpar@1
|
1800 |
|
alpar@1
|
1801 |
\begin{footnotesize}
|
alpar@1
|
1802 |
\begin{verbatim}
|
alpar@1
|
1803 |
Reading problem data from `25fv47.mps'...
|
alpar@1
|
1804 |
Problem: 25FV47
|
alpar@1
|
1805 |
Objective: R0000
|
alpar@1
|
1806 |
822 rows, 1571 columns, 11127 non-zeros
|
alpar@1
|
1807 |
6919 records were read
|
alpar@1
|
1808 |
Crashing...
|
alpar@1
|
1809 |
Size of triangular part = 799
|
alpar@1
|
1810 |
0: obj = 1.627307307e+04 infeas = 5.194e+04 (23)
|
alpar@1
|
1811 |
200: obj = 1.474901610e+04 infeas = 1.233e+04 (19)
|
alpar@1
|
1812 |
400: obj = 1.343909995e+04 infeas = 3.648e+03 (13)
|
alpar@1
|
1813 |
600: obj = 1.756052217e+04 infeas = 4.179e+02 (7)
|
alpar@1
|
1814 |
* 775: obj = 1.789251591e+04 infeas = 4.982e-14 (1)
|
alpar@1
|
1815 |
* 800: obj = 1.663354510e+04 infeas = 2.857e-14 (1)
|
alpar@1
|
1816 |
* 1000: obj = 1.024935068e+04 infeas = 1.958e-12 (1)
|
alpar@1
|
1817 |
* 1200: obj = 7.860174791e+03 infeas = 2.810e-29 (1)
|
alpar@1
|
1818 |
* 1400: obj = 6.642378184e+03 infeas = 2.036e-16 (1)
|
alpar@1
|
1819 |
* 1600: obj = 6.037014568e+03 infeas = 0.000e+00 (1)
|
alpar@1
|
1820 |
* 1800: obj = 5.662171307e+03 infeas = 6.447e-15 (1)
|
alpar@1
|
1821 |
* 2000: obj = 5.528146165e+03 infeas = 9.764e-13 (1)
|
alpar@1
|
1822 |
* 2125: obj = 5.501845888e+03 infeas = 0.000e+00 (1)
|
alpar@1
|
1823 |
OPTIMAL SOLUTION FOUND
|
alpar@1
|
1824 |
Writing basic solution to `25fv47.txt'...
|
alpar@1
|
1825 |
\end{verbatim}
|
alpar@1
|
1826 |
\end{footnotesize}
|
alpar@1
|
1827 |
|
alpar@1
|
1828 |
\newpage
|
alpar@1
|
1829 |
|
alpar@1
|
1830 |
\subsubsection*{Example 2}
|
alpar@1
|
1831 |
|
alpar@1
|
1832 |
The following main program solves the same LP problem instance as in
|
alpar@1
|
1833 |
Example 1 above, however, it uses the dual simplex method, which starts
|
alpar@1
|
1834 |
from the standard initial basis.
|
alpar@1
|
1835 |
|
alpar@1
|
1836 |
\begin{footnotesize}
|
alpar@1
|
1837 |
\begin{verbatim}
|
alpar@1
|
1838 |
/* spxsamp2.c */
|
alpar@1
|
1839 |
|
alpar@1
|
1840 |
#include <stdio.h>
|
alpar@1
|
1841 |
#include <stdlib.h>
|
alpar@1
|
1842 |
#include <glpk.h>
|
alpar@1
|
1843 |
|
alpar@1
|
1844 |
int main(void)
|
alpar@1
|
1845 |
{ glp_prob *P;
|
alpar@1
|
1846 |
glp_smcp parm;
|
alpar@1
|
1847 |
P = glp_create_prob();
|
alpar@1
|
1848 |
glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps");
|
alpar@1
|
1849 |
glp_init_smcp(&parm);
|
alpar@1
|
1850 |
parm.meth = GLP_DUAL;
|
alpar@1
|
1851 |
glp_simplex(P, &parm);
|
alpar@1
|
1852 |
glp_print_sol(P, "25fv47.txt");
|
alpar@1
|
1853 |
glp_delete_prob(P);
|
alpar@1
|
1854 |
return 0;
|
alpar@1
|
1855 |
}
|
alpar@1
|
1856 |
|
alpar@1
|
1857 |
/* eof */
|
alpar@1
|
1858 |
\end{verbatim}
|
alpar@1
|
1859 |
\end{footnotesize}
|
alpar@1
|
1860 |
|
alpar@1
|
1861 |
\noindent
|
alpar@1
|
1862 |
Below here is shown the terminal output from this example program.
|
alpar@1
|
1863 |
|
alpar@1
|
1864 |
\begin{footnotesize}
|
alpar@1
|
1865 |
\begin{verbatim}
|
alpar@1
|
1866 |
Reading problem data from `25fv47.mps'...
|
alpar@1
|
1867 |
Problem: 25FV47
|
alpar@1
|
1868 |
Objective: R0000
|
alpar@1
|
1869 |
822 rows, 1571 columns, 11127 non-zeros
|
alpar@1
|
1870 |
6919 records were read
|
alpar@1
|
1871 |
0: infeas = 1.223e+03 (516)
|
alpar@1
|
1872 |
200: infeas = 7.000e+00 (471)
|
alpar@1
|
1873 |
240: infeas = 1.106e-14 (461)
|
alpar@1
|
1874 |
| 400: obj = -5.394267152e+03 infeas = 5.571e-16 (391)
|
alpar@1
|
1875 |
| 600: obj = -4.586395752e+03 infeas = 1.389e-15 (340)
|
alpar@1
|
1876 |
| 800: obj = -4.158268146e+03 infeas = 1.640e-15 (264)
|
alpar@1
|
1877 |
| 1000: obj = -3.725320045e+03 infeas = 5.181e-15 (245)
|
alpar@1
|
1878 |
| 1200: obj = -3.104802163e+03 infeas = 1.019e-14 (210)
|
alpar@1
|
1879 |
| 1400: obj = -2.584190499e+03 infeas = 8.865e-15 (178)
|
alpar@1
|
1880 |
| 1600: obj = -2.073852927e+03 infeas = 7.867e-15 (142)
|
alpar@1
|
1881 |
| 1800: obj = -1.164037407e+03 infeas = 8.792e-15 (109)
|
alpar@1
|
1882 |
| 2000: obj = -4.370590250e+02 infeas = 2.591e-14 (85)
|
alpar@1
|
1883 |
| 2200: obj = 1.068240144e+03 infeas = 1.025e-13 (70)
|
alpar@1
|
1884 |
| 2400: obj = 1.607481126e+03 infeas = 3.272e-14 (67)
|
alpar@1
|
1885 |
| 2600: obj = 3.038230551e+03 infeas = 4.850e-14 (52)
|
alpar@1
|
1886 |
| 2800: obj = 4.316238187e+03 infeas = 2.622e-14 (36)
|
alpar@1
|
1887 |
| 3000: obj = 5.443842629e+03 infeas = 3.976e-15 (11)
|
alpar@1
|
1888 |
| 3060: obj = 5.501845888e+03 infeas = 8.806e-15 (2)
|
alpar@1
|
1889 |
OPTIMAL SOLUTION FOUND
|
alpar@1
|
1890 |
Writing basic solution to `25fv47.txt'...
|
alpar@1
|
1891 |
\end{verbatim}
|
alpar@1
|
1892 |
\end{footnotesize}
|
alpar@1
|
1893 |
|
alpar@1
|
1894 |
\subsection{glp\_exact---solve LP problem in exact arithmetic}
|
alpar@1
|
1895 |
|
alpar@1
|
1896 |
\subsubsection*{Synopsis}
|
alpar@1
|
1897 |
|
alpar@1
|
1898 |
\begin{verbatim}
|
alpar@1
|
1899 |
int glp_exact(glp_prob *lp, const glp_smcp *parm);
|
alpar@1
|
1900 |
\end{verbatim}
|
alpar@1
|
1901 |
|
alpar@1
|
1902 |
\subsubsection*{Description}
|
alpar@1
|
1903 |
|
alpar@1
|
1904 |
The routine \verb|glp_exact| is a tentative implementation of the
|
alpar@1
|
1905 |
primal two-phase simplex method based on exact (rational) arithmetic.
|
alpar@1
|
1906 |
It is similar to the routine \verb|glp_simplex|, however, for all
|
alpar@1
|
1907 |
internal computations it uses arithmetic of rational numbers, which is
|
alpar@1
|
1908 |
exact in mathematical sense, i.e. free of round-off errors unlike
|
alpar@1
|
1909 |
floating-point arithmetic.
|
alpar@1
|
1910 |
|
alpar@1
|
1911 |
Note that the routine \verb|glp_exact| uses only two control parameters
|
alpar@1
|
1912 |
passed in the structure \verb|glp_smcp|, namely, \verb|it_lim| and
|
alpar@1
|
1913 |
\verb|tm_lim|.
|
alpar@1
|
1914 |
|
alpar@1
|
1915 |
\subsubsection*{Returns}
|
alpar@1
|
1916 |
|
alpar@1
|
1917 |
\def\arraystretch{1}
|
alpar@1
|
1918 |
|
alpar@1
|
1919 |
\begin{tabular}{@{}p{25mm}p{97.3mm}@{}}
|
alpar@1
|
1920 |
0 & The LP problem instance has been successfully solved. (This code
|
alpar@1
|
1921 |
does {\it not} necessarily mean that the solver has found optimal
|
alpar@1
|
1922 |
solution. It only means that the solution process was successful.) \\
|
alpar@1
|
1923 |
\verb|GLP_EBADB| & Unable to start the search, because the initial basis
|
alpar@1
|
1924 |
specified in the problem object is invalid---the number of basic
|
alpar@1
|
1925 |
(auxiliary and structural) variables is not the same as the number of
|
alpar@1
|
1926 |
rows in the problem object.\\
|
alpar@1
|
1927 |
\verb|GLP_ESING| & Unable to start the search, because the basis matrix
|
alpar@1
|
1928 |
corresponding to the initial basis is exactly singular.\\
|
alpar@1
|
1929 |
\verb|GLP_EBOUND| & Unable to start the search, because some
|
alpar@1
|
1930 |
double-bounded (auxiliary or structural) variables have incorrect
|
alpar@1
|
1931 |
bounds.\\
|
alpar@1
|
1932 |
\verb|GLP_EFAIL| & The problem instance has no rows/columns.\\
|
alpar@1
|
1933 |
\verb|GLP_EITLIM| & The search was prematurely terminated, because the
|
alpar@1
|
1934 |
simplex iteration limit has been exceeded.\\
|
alpar@1
|
1935 |
\verb|GLP_ETMLIM| & The search was prematurely terminated, because the
|
alpar@1
|
1936 |
time limit has been exceeded.\\
|
alpar@1
|
1937 |
\end{tabular}
|
alpar@1
|
1938 |
|
alpar@1
|
1939 |
\subsubsection*{Comments}
|
alpar@1
|
1940 |
|
alpar@1
|
1941 |
Computations in exact arithmetic are very time consuming, so solving
|
alpar@1
|
1942 |
LP problem with the routine \verb|glp_exact| from the very beginning is
|
alpar@1
|
1943 |
not a good idea. It is much better at first to find an optimal basis
|
alpar@1
|
1944 |
with the routine \verb|glp_simplex| and only then to call
|
alpar@1
|
1945 |
\verb|glp_exact|, in which case only a few simplex iterations need to
|
alpar@1
|
1946 |
be performed in exact arithmetic.
|
alpar@1
|
1947 |
|
alpar@1
|
1948 |
\subsection{glp\_init\_smcp---initialize simplex solver control
|
alpar@1
|
1949 |
parameters}
|
alpar@1
|
1950 |
|
alpar@1
|
1951 |
\subsubsection*{Synopsis}
|
alpar@1
|
1952 |
|
alpar@1
|
1953 |
\begin{verbatim}
|
alpar@1
|
1954 |
int glp_init_smcp(glp_smcp *parm);
|
alpar@1
|
1955 |
\end{verbatim}
|
alpar@1
|
1956 |
|
alpar@1
|
1957 |
\subsubsection*{Description}
|
alpar@1
|
1958 |
|
alpar@1
|
1959 |
The routine \verb|glp_init_smcp| initializes control parameters, which
|
alpar@1
|
1960 |
are used by the simplex solver, with default values.
|
alpar@1
|
1961 |
|
alpar@1
|
1962 |
Default values of the control parameters are stored in a \verb|glp_smcp|
|
alpar@1
|
1963 |
structure, which the parameter \verb|parm| points to.
|
alpar@1
|
1964 |
|
alpar@1
|
1965 |
\subsection{glp\_get\_status---determine generic status of basic
|
alpar@1
|
1966 |
solution}
|
alpar@1
|
1967 |
|
alpar@1
|
1968 |
\subsubsection*{Synopsis}
|
alpar@1
|
1969 |
|
alpar@1
|
1970 |
\begin{verbatim}
|
alpar@1
|
1971 |
int glp_get_status(glp_prob *lp);
|
alpar@1
|
1972 |
\end{verbatim}
|
alpar@1
|
1973 |
|
alpar@1
|
1974 |
\subsubsection*{Returns}
|
alpar@1
|
1975 |
|
alpar@1
|
1976 |
The routine \verb|glp_get_status| reports the generic status of the
|
alpar@1
|
1977 |
current basic solution for the specified problem object as follows:
|
alpar@1
|
1978 |
|
alpar@1
|
1979 |
\begin{tabular}{@{}ll}
|
alpar@1
|
1980 |
\verb|GLP_OPT| & solution is optimal; \\
|
alpar@1
|
1981 |
\verb|GLP_FEAS| & solution is feasible; \\
|
alpar@1
|
1982 |
\verb|GLP_INFEAS| & solution is infeasible; \\
|
alpar@1
|
1983 |
\verb|GLP_NOFEAS| & problem has no feasible solution; \\
|
alpar@1
|
1984 |
\verb|GLP_UNBND| & problem has unbounded solution; \\
|
alpar@1
|
1985 |
\verb|GLP_UNDEF| & solution is undefined. \\
|
alpar@1
|
1986 |
\end{tabular}
|
alpar@1
|
1987 |
|
alpar@1
|
1988 |
More detailed information about the status of basic solution can be
|
alpar@1
|
1989 |
retrieved with the routines \verb|glp_get_prim_stat| and
|
alpar@1
|
1990 |
\verb|glp_get_dual_stat|.
|
alpar@1
|
1991 |
|
alpar@1
|
1992 |
\newpage
|
alpar@1
|
1993 |
|
alpar@1
|
1994 |
\subsection{glp\_get\_prim\_stat---retrieve status of primal basic
|
alpar@1
|
1995 |
solution}
|
alpar@1
|
1996 |
|
alpar@1
|
1997 |
\subsubsection*{Synopsis}
|
alpar@1
|
1998 |
|
alpar@1
|
1999 |
\begin{verbatim}
|
alpar@1
|
2000 |
int glp_get_prim_stat(glp_prob *lp);
|
alpar@1
|
2001 |
\end{verbatim}
|
alpar@1
|
2002 |
|
alpar@1
|
2003 |
\subsubsection*{Returns}
|
alpar@1
|
2004 |
|
alpar@1
|
2005 |
The routine \verb|glp_get_prim_stat| reports the status of the primal
|
alpar@1
|
2006 |
basic solution for the specified problem object as follows:
|
alpar@1
|
2007 |
|
alpar@1
|
2008 |
\begin{tabular}{@{}ll}
|
alpar@1
|
2009 |
\verb|GLP_UNDEF| & primal solution is undefined; \\
|
alpar@1
|
2010 |
\verb|GLP_FEAS| & primal solution is feasible; \\
|
alpar@1
|
2011 |
\verb|GLP_INFEAS| & primal solution is infeasible; \\
|
alpar@1
|
2012 |
\verb|GLP_NOFEAS| & no primal feasible solution exists. \\
|
alpar@1
|
2013 |
\end{tabular}
|
alpar@1
|
2014 |
|
alpar@1
|
2015 |
\subsection{glp\_get\_dual\_stat---retrieve status of dual basic
|
alpar@1
|
2016 |
solution}
|
alpar@1
|
2017 |
|
alpar@1
|
2018 |
\subsubsection*{Synopsis}
|
alpar@1
|
2019 |
|
alpar@1
|
2020 |
\begin{verbatim}
|
alpar@1
|
2021 |
int glp_get_dual_stat(glp_prob *lp);
|
alpar@1
|
2022 |
\end{verbatim}
|
alpar@1
|
2023 |
|
alpar@1
|
2024 |
\subsubsection*{Returns}
|
alpar@1
|
2025 |
|
alpar@1
|
2026 |
The routine \verb|glp_get_dual_stat| reports the status of the dual
|
alpar@1
|
2027 |
basic solution for the specified problem object as follows:
|
alpar@1
|
2028 |
|
alpar@1
|
2029 |
\begin{tabular}{@{}ll}
|
alpar@1
|
2030 |
\verb|GLP_UNDEF| & dual solution is undefined; \\
|
alpar@1
|
2031 |
\verb|GLP_FEAS| & dual solution is feasible; \\
|
alpar@1
|
2032 |
\verb|GLP_INFEAS| & dual solution is infeasible; \\
|
alpar@1
|
2033 |
\verb|GLP_NOFEAS| & no dual feasible solution exists. \\
|
alpar@1
|
2034 |
\end{tabular}
|
alpar@1
|
2035 |
|
alpar@1
|
2036 |
\subsection{glp\_get\_obj\_val---retrieve objective value}
|
alpar@1
|
2037 |
|
alpar@1
|
2038 |
\subsubsection*{Synopsis}
|
alpar@1
|
2039 |
|
alpar@1
|
2040 |
\begin{verbatim}
|
alpar@1
|
2041 |
double glp_get_obj_val(glp_prob *lp);
|
alpar@1
|
2042 |
\end{verbatim}
|
alpar@1
|
2043 |
|
alpar@1
|
2044 |
\subsubsection*{Returns}
|
alpar@1
|
2045 |
|
alpar@1
|
2046 |
The routine \verb|glp_get_obj_val| returns current value of the
|
alpar@1
|
2047 |
objective function.
|
alpar@1
|
2048 |
|
alpar@1
|
2049 |
\subsection{glp\_get\_row\_stat---retrieve row status}
|
alpar@1
|
2050 |
|
alpar@1
|
2051 |
\subsubsection*{Synopsis}
|
alpar@1
|
2052 |
|
alpar@1
|
2053 |
\begin{verbatim}
|
alpar@1
|
2054 |
int glp_get_row_stat(glp_prob *lp, int i);
|
alpar@1
|
2055 |
\end{verbatim}
|
alpar@1
|
2056 |
|
alpar@1
|
2057 |
\subsubsection*{Returns}
|
alpar@1
|
2058 |
|
alpar@1
|
2059 |
The routine \verb|glp_get_row_stat| returns current status assigned to
|
alpar@1
|
2060 |
the auxiliary variable associated with \verb|i|-th row as follows:
|
alpar@1
|
2061 |
|
alpar@1
|
2062 |
\begin{tabular}{@{}ll}
|
alpar@1
|
2063 |
\verb|GLP_BS| & basic variable; \\
|
alpar@1
|
2064 |
\verb|GLP_NL| & non-basic variable on its lower bound; \\
|
alpar@1
|
2065 |
\verb|GLP_NU| & non-basic variable on its upper bound; \\
|
alpar@1
|
2066 |
\verb|GLP_NF| & non-basic free (unbounded) variable; \\
|
alpar@1
|
2067 |
\verb|GLP_NS| & non-basic fixed variable. \\
|
alpar@1
|
2068 |
\end{tabular}
|
alpar@1
|
2069 |
|
alpar@1
|
2070 |
\subsection{glp\_get\_row\_prim---retrieve row primal value}
|
alpar@1
|
2071 |
|
alpar@1
|
2072 |
\subsubsection*{Synopsis}
|
alpar@1
|
2073 |
|
alpar@1
|
2074 |
\begin{verbatim}
|
alpar@1
|
2075 |
double glp_get_row_prim(glp_prob *lp, int i);
|
alpar@1
|
2076 |
\end{verbatim}
|
alpar@1
|
2077 |
|
alpar@1
|
2078 |
\subsubsection*{Returns}
|
alpar@1
|
2079 |
|
alpar@1
|
2080 |
The routine \verb|glp_get_row_prim| returns primal value of the
|
alpar@1
|
2081 |
auxiliary variable associated with \verb|i|-th row.
|
alpar@1
|
2082 |
|
alpar@1
|
2083 |
\subsection{glp\_get\_row\_dual---retrieve row dual value}
|
alpar@1
|
2084 |
|
alpar@1
|
2085 |
\subsubsection*{Synopsis}
|
alpar@1
|
2086 |
|
alpar@1
|
2087 |
\begin{verbatim}
|
alpar@1
|
2088 |
double glp_get_row_dual(glp_prob *lp, int i);
|
alpar@1
|
2089 |
\end{verbatim}
|
alpar@1
|
2090 |
|
alpar@1
|
2091 |
\subsubsection*{Returns}
|
alpar@1
|
2092 |
|
alpar@1
|
2093 |
The routine \verb|glp_get_row_dual| returns dual value (i.e. reduced
|
alpar@1
|
2094 |
cost) of the auxiliary variable associated with \verb|i|-th row.
|
alpar@1
|
2095 |
|
alpar@1
|
2096 |
\newpage
|
alpar@1
|
2097 |
|
alpar@1
|
2098 |
\subsection{glp\_get\_col\_stat---retrieve column status}
|
alpar@1
|
2099 |
|
alpar@1
|
2100 |
\subsubsection*{Synopsis}
|
alpar@1
|
2101 |
|
alpar@1
|
2102 |
\begin{verbatim}
|
alpar@1
|
2103 |
int glp_get_col_stat(glp_prob *lp, int j);
|
alpar@1
|
2104 |
\end{verbatim}
|
alpar@1
|
2105 |
|
alpar@1
|
2106 |
\subsubsection*{Returns}
|
alpar@1
|
2107 |
|
alpar@1
|
2108 |
The routine \verb|glp_get_col_stat| returns current status assigned to
|
alpar@1
|
2109 |
the structural variable associated with \verb|j|-th column as follows:
|
alpar@1
|
2110 |
|
alpar@1
|
2111 |
\begin{tabular}{@{}ll}
|
alpar@1
|
2112 |
\verb|GLP_BS| & basic variable; \\
|
alpar@1
|
2113 |
\verb|GLP_NL| & non-basic variable on its lower bound; \\
|
alpar@1
|
2114 |
\verb|GLP_NU| & non-basic variable on its upper bound; \\
|
alpar@1
|
2115 |
\verb|GLP_NF| & non-basic free (unbounded) variable; \\
|
alpar@1
|
2116 |
\verb|GLP_NS| & non-basic fixed variable. \\
|
alpar@1
|
2117 |
\end{tabular}
|
alpar@1
|
2118 |
|
alpar@1
|
2119 |
\subsection{glp\_get\_col\_prim---retrieve column primal value}
|
alpar@1
|
2120 |
|
alpar@1
|
2121 |
\subsubsection*{Synopsis}
|
alpar@1
|
2122 |
|
alpar@1
|
2123 |
\begin{verbatim}
|
alpar@1
|
2124 |
double glp_get_col_prim(glp_prob *lp, int j);
|
alpar@1
|
2125 |
\end{verbatim}
|
alpar@1
|
2126 |
|
alpar@1
|
2127 |
\subsubsection*{Returns}
|
alpar@1
|
2128 |
|
alpar@1
|
2129 |
The routine \verb|glp_get_col_prim| returns primal value of the
|
alpar@1
|
2130 |
structural variable associated with \verb|j|-th column.
|
alpar@1
|
2131 |
|
alpar@1
|
2132 |
\subsection{glp\_get\_col\_dual---retrieve column dual value}
|
alpar@1
|
2133 |
|
alpar@1
|
2134 |
\subsubsection*{Synopsis}
|
alpar@1
|
2135 |
|
alpar@1
|
2136 |
\begin{verbatim}
|
alpar@1
|
2137 |
double glp_get_col_dual(glp_prob *lp, int j);
|
alpar@1
|
2138 |
\end{verbatim}
|
alpar@1
|
2139 |
|
alpar@1
|
2140 |
\subsubsection*{Returns}
|
alpar@1
|
2141 |
|
alpar@1
|
2142 |
The routine \verb|glp_get_col_dual| returns dual value (i.e. reduced
|
alpar@1
|
2143 |
cost) of the structural variable associated with \verb|j|-th column.
|
alpar@1
|
2144 |
|
alpar@1
|
2145 |
\newpage
|
alpar@1
|
2146 |
|
alpar@1
|
2147 |
\subsection{glp\_get\_unbnd\_ray---determine variable causing\\
|
alpar@1
|
2148 |
unboundedness}
|
alpar@1
|
2149 |
|
alpar@1
|
2150 |
\subsubsection*{Synopsis}
|
alpar@1
|
2151 |
|
alpar@1
|
2152 |
\begin{verbatim}
|
alpar@1
|
2153 |
int glp_get_unbnd_ray(glp_prob *lp);
|
alpar@1
|
2154 |
\end{verbatim}
|
alpar@1
|
2155 |
|
alpar@1
|
2156 |
\subsubsection*{Returns}
|
alpar@1
|
2157 |
|
alpar@1
|
2158 |
The routine \verb|glp_get_unbnd_ray| returns the number $k$ of
|
alpar@1
|
2159 |
a variable, which causes primal or dual unboundedness.
|
alpar@1
|
2160 |
If $1\leq k\leq m$, it is $k$-th auxiliary variable, and if
|
alpar@1
|
2161 |
$m+1\leq k\leq m+n$, it is $(k-m)$-th structural variable, where $m$ is
|
alpar@1
|
2162 |
the number of rows, $n$ is the number of columns in the problem object.
|
alpar@1
|
2163 |
If such variable is not defined, the routine returns 0.
|
alpar@1
|
2164 |
|
alpar@1
|
2165 |
\subsubsection*{Comments}
|
alpar@1
|
2166 |
|
alpar@1
|
2167 |
If it is not exactly known which version of the simplex solver
|
alpar@1
|
2168 |
detected unboundedness, i.e. whether the unboundedness is primal or
|
alpar@1
|
2169 |
dual, it is sufficient to check the status of the variable
|
alpar@1
|
2170 |
with the routine \verb|glp_get_row_stat| or \verb|glp_get_col_stat|.
|
alpar@1
|
2171 |
If the variable is non-basic, the unboundedness is primal, otherwise,
|
alpar@1
|
2172 |
if the variable is basic, the unboundedness is dual (the latter case
|
alpar@1
|
2173 |
means that the problem has no primal feasible dolution).
|
alpar@1
|
2174 |
|
alpar@1
|
2175 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
alpar@1
|
2176 |
|
alpar@1
|
2177 |
\newpage
|
alpar@1
|
2178 |
|
alpar@1
|
2179 |
\section{Interior-point method routines}
|
alpar@1
|
2180 |
|
alpar@1
|
2181 |
{\it Interior-point methods} (also known as {\it barrier methods}) are
|
alpar@1
|
2182 |
more modern and powerful numerical methods for large-scale linear
|
alpar@1
|
2183 |
programming. Such methods are especially efficient for very sparse LP
|
alpar@1
|
2184 |
problems and allow solving such problems much faster than the simplex
|
alpar@1
|
2185 |
method.
|
alpar@1
|
2186 |
|
alpar@1
|
2187 |
In brief, the GLPK interior-point solver works as follows.
|
alpar@1
|
2188 |
|
alpar@1
|
2189 |
At first, the solver transforms the original LP to a {\it working} LP
|
alpar@1
|
2190 |
in the standard format:
|
alpar@1
|
2191 |
|
alpar@1
|
2192 |
\medskip
|
alpar@1
|
2193 |
|
alpar@1
|
2194 |
\noindent
|
alpar@1
|
2195 |
\hspace{.5in} minimize
|
alpar@1
|
2196 |
$$z = c_1x_{m+1} + c_2x_{m+2} + \dots + c_nx_{m+n} + c_0 \eqno (2.4)$$
|
alpar@1
|
2197 |
\hspace{.5in} subject to linear constraints
|
alpar@1
|
2198 |
$$
|
alpar@1
|
2199 |
\begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}l}
|
alpar@1
|
2200 |
a_{11}x_{m+1}&+&a_{12}x_{m+2}&+ \dots +&a_{1n}x_{m+n}&=&b_1 \\
|
alpar@1
|
2201 |
a_{21}x_{m+1}&+&a_{22}x_{m+2}&+ \dots +&a_{2n}x_{m+n}&=&b_2 \\
|
alpar@1
|
2202 |
\multicolumn{7}{c}
|
alpar@1
|
2203 |
{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .} \\
|
alpar@1
|
2204 |
a_{m1}x_{m+1}&+&a_{m2}x_{m+2}&+ \dots +&a_{mn}x_{m+n}&=&b_m \\
|
alpar@1
|
2205 |
\end{array} \eqno (2.5)
|
alpar@1
|
2206 |
$$
|
alpar@1
|
2207 |
\hspace{.5in} and non-negative variables
|
alpar@1
|
2208 |
$$x_1\geq 0,\ \ x_2\geq 0,\ \ \dots,\ \ x_n\geq 0 \eqno(2.6)$$
|
alpar@1
|
2209 |
where: $z$ is the objective function; $x_1$, \dots, $x_n$ are variables;
|
alpar@1
|
2210 |
$c_1$, \dots, $c_n$ are objective coefficients; $c_0$ is a constant term
|
alpar@1
|
2211 |
of the objective function;\linebreak $a_{11}$, \dots, $a_{mn}$ are
|
alpar@1
|
2212 |
constraint coefficients; $b_1$, \dots, $b_m$ are right-hand sides.
|
alpar@1
|
2213 |
|
alpar@1
|
2214 |
Using vector and matrix notations the working LP (2.4)---(2.6) can be
|
alpar@1
|
2215 |
written as follows:
|
alpar@1
|
2216 |
$$z=c^Tx+c_0\ \rightarrow\ \min,\eqno(2.7)$$
|
alpar@1
|
2217 |
$$Ax=b,\eqno(2.8)$$
|
alpar@1
|
2218 |
$$x\geq 0,\eqno(2.9)$$
|
alpar@1
|
2219 |
where: $x=(x_j)$ is $n$-vector of variables, $c=(c_j)$ is $n$-vector of
|
alpar@1
|
2220 |
objective coefficients, $A=(a_{ij})$ is $m\times n$-matrix of
|
alpar@1
|
2221 |
constraint coefficients, and $b=(b_i)$ is $m$-vector of right-hand
|
alpar@1
|
2222 |
sides.
|
alpar@1
|
2223 |
|
alpar@1
|
2224 |
Karush--Kuhn--Tucker optimality conditions for LP (2.7)---(2.9) are the
|
alpar@1
|
2225 |
following:
|
alpar@1
|
2226 |
|
alpar@1
|
2227 |
\newpage
|
alpar@1
|
2228 |
|
alpar@1
|
2229 |
$$Ax=b,\eqno(2.10)$$
|
alpar@1
|
2230 |
$$A^T\pi+\lambda=c,\eqno(2.11)$$
|
alpar@1
|
2231 |
$$\lambda^Tx=0,\eqno(2.12)$$
|
alpar@1
|
2232 |
$$x\geq 0,\ \ \lambda\geq 0,\eqno(2.13)$$
|
alpar@1
|
2233 |
where: $\pi$ is $m$-vector of Lagrange multipliers (dual variables) for
|
alpar@1
|
2234 |
equality constraints (2.8), $\lambda$ is $n$-vector of Lagrange
|
alpar@1
|
2235 |
multipliers (dual variables) for non-negativity constraints (2.9),
|
alpar@1
|
2236 |
(2.10) is the primal feasibility condition, (2.11) is the dual
|
alpar@1
|
2237 |
feasibility condition, (2.12) is the primal-dual complementarity
|
alpar@1
|
2238 |
condition, and (2.13) is the non-negativity conditions.
|
alpar@1
|
2239 |
|
alpar@1
|
2240 |
The main idea of the primal-dual interior-point method is based on
|
alpar@1
|
2241 |
finding a point in the primal-dual space (i.e. in the space of all
|
alpar@1
|
2242 |
primal and dual variables $x$, $\pi$, and $\lambda$), which satisfies
|
alpar@1
|
2243 |
to all optimality conditions (2.10)---(2.13). Obviously, $x$-component
|
alpar@1
|
2244 |
of such point then provides an optimal solution to the working LP
|
alpar@1
|
2245 |
(2.7)---(2.9).
|
alpar@1
|
2246 |
|
alpar@1
|
2247 |
To find the optimal point $(x^*,\pi^*,\lambda^*)$ the interior-point
|
alpar@1
|
2248 |
method attempts to solve the system of equations (2.10)---(2.12), which
|
alpar@1
|
2249 |
is closed in the sense that the number of variables $x_j$, $\pi_i$, and
|
alpar@1
|
2250 |
$\lambda_j$ and the number equations are the same and equal to $m+2n$.
|
alpar@1
|
2251 |
Due to condition (2.12) this system of equations is non-linear, so it
|
alpar@1
|
2252 |
can be solved with a version of {\it Newton's method} provided with
|
alpar@1
|
2253 |
additional rules to keep the current point within the positive orthant
|
alpar@1
|
2254 |
as required by the non-negativity conditions (2.13).
|
alpar@1
|
2255 |
|
alpar@1
|
2256 |
Finally, once the optimal point $(x^*,\pi^*,\lambda^*)$ has been found,
|
alpar@1
|
2257 |
the solver performs inverse transformations to recover corresponding
|
alpar@1
|
2258 |
solution to the original LP passed to the solver from the application
|
alpar@1
|
2259 |
program.
|
alpar@1
|
2260 |
|
alpar@1
|
2261 |
\subsection{glp\_interior---solve LP problem with the interior-point
|
alpar@1
|
2262 |
method}
|
alpar@1
|
2263 |
|
alpar@1
|
2264 |
\subsubsection*{Synopsis}
|
alpar@1
|
2265 |
|
alpar@1
|
2266 |
\begin{verbatim}
|
alpar@1
|
2267 |
int glp_interior(glp_prob *P, const glp_iptcp *parm);
|
alpar@1
|
2268 |
\end{verbatim}
|
alpar@1
|
2269 |
|
alpar@1
|
2270 |
\subsubsection*{Description}
|
alpar@1
|
2271 |
|
alpar@1
|
2272 |
The routine \verb|glp_interior| is a driver to the LP solver based on
|
alpar@1
|
2273 |
the primal-dual interior-point method. This routine retrieves problem
|
alpar@1
|
2274 |
data from the specified problem object, calls the solver to solve the
|
alpar@1
|
2275 |
problem instance, and stores results of computations back into the
|
alpar@1
|
2276 |
problem object.
|
alpar@1
|
2277 |
|
alpar@1
|
2278 |
The interior-point solver has a set of control parameters. Values of
|
alpar@1
|
2279 |
the control parameters can be passed in the structure \verb|glp_iptcp|,
|
alpar@1
|
2280 |
which the parameter \verb|parm| points to. For detailed description of
|
alpar@1
|
2281 |
this structure see paragraph ``Control parameters'' below. Before
|
alpar@1
|
2282 |
specifying some control parameters the application program should
|
alpar@1
|
2283 |
initialize the structure \verb|glp_iptcp| by default values of all
|
alpar@1
|
2284 |
control parameters using the routine \verb|glp_init_iptcp| (see the
|
alpar@1
|
2285 |
next subsection). This is needed for backward compatibility, because in
|
alpar@1
|
2286 |
the future there may appear new members in the structure
|
alpar@1
|
2287 |
\verb|glp_iptcp|.
|
alpar@1
|
2288 |
|
alpar@1
|
2289 |
The parameter \verb|parm| can be specified as \verb|NULL|, in which
|
alpar@1
|
2290 |
case the solver uses default settings.
|
alpar@1
|
2291 |
|
alpar@1
|
2292 |
\subsubsection*{Returns}
|
alpar@1
|
2293 |
|
alpar@1
|
2294 |
\def\arraystretch{1}
|
alpar@1
|
2295 |
|
alpar@1
|
2296 |
\begin{tabular}{@{}p{25mm}p{97.3mm}@{}}
|
alpar@1
|
2297 |
0 & The LP problem instance has been successfully solved. (This code
|
alpar@1
|
2298 |
does {\it not} necessarily mean that the solver has found optimal
|
alpar@1
|
2299 |
solution. It only means that the solution process was successful.) \\
|
alpar@1
|
2300 |
\verb|GLP_EFAIL| & The problem has no rows/columns.\\
|
alpar@1
|
2301 |
\verb|GLP_ENOCVG| & Very slow convergence or divergence.\\
|
alpar@1
|
2302 |
\verb|GLP_EITLIM| & Iteration limit exceeded.\\
|
alpar@1
|
2303 |
\verb|GLP_EINSTAB| & Numerical instability on solving Newtonian
|
alpar@1
|
2304 |
system.\\
|
alpar@1
|
2305 |
\end{tabular}
|
alpar@1
|
2306 |
|
alpar@1
|
2307 |
\subsubsection*{Comments}
|
alpar@1
|
2308 |
|
alpar@1
|
2309 |
The routine \verb|glp_interior| implements an easy version of
|
alpar@1
|
2310 |
the primal-dual interior-point method based on Mehrotra's
|
alpar@1
|
2311 |
technique.\footnote{S. Mehrotra. On the implementation of a primal-dual
|
alpar@1
|
2312 |
interior point method. SIAM J. on Optim., 2(4), pp. 575-601, 1992.}
|
alpar@1
|
2313 |
|
alpar@1
|
2314 |
Note that currently the GLPK interior-point solver does not include
|
alpar@1
|
2315 |
many important features, in particular:
|
alpar@1
|
2316 |
|
alpar@1
|
2317 |
$\bullet$ it is not able to process dense columns. Thus, if the
|
alpar@1
|
2318 |
constraint matrix of the LP problem has dense columns, the solving
|
alpar@1
|
2319 |
process may be inefficient;
|
alpar@1
|
2320 |
|
alpar@1
|
2321 |
$\bullet$ it has no features against numerical instability. For some
|
alpar@1
|
2322 |
LP problems premature termination may happen if the matrix $ADA^T$
|
alpar@1
|
2323 |
becomes singular or ill-conditioned;
|
alpar@1
|
2324 |
|
alpar@1
|
2325 |
$\bullet$ it is not able to identify the optimal basis, which
|
alpar@1
|
2326 |
corresponds to the interior-point solution found.
|
alpar@1
|
2327 |
|
alpar@1
|
2328 |
\newpage
|
alpar@1
|
2329 |
|
alpar@1
|
2330 |
\subsubsection*{Terminal output}
|
alpar@1
|
2331 |
|
alpar@1
|
2332 |
Solving large LP problems may take a long time, so the solver reports
|
alpar@1
|
2333 |
some information about every interior-point iteration,\footnote{Unlike
|
alpar@1
|
2334 |
the simplex method the interior point method usually needs 30---50
|
alpar@1
|
2335 |
iterations (independently on the problem size) in order to find an
|
alpar@1
|
2336 |
optimal solution.} which is sent to the terminal. This information has
|
alpar@1
|
2337 |
the following format:
|
alpar@1
|
2338 |
|
alpar@1
|
2339 |
\begin{verbatim}
|
alpar@1
|
2340 |
nnn: obj = fff; rpi = ppp; rdi = ddd; gap = ggg
|
alpar@1
|
2341 |
\end{verbatim}
|
alpar@1
|
2342 |
|
alpar@1
|
2343 |
\noindent where: \verb|nnn| is iteration number, \verb|fff| is the
|
alpar@1
|
2344 |
current value of the objective function (in the case of maximization it
|
alpar@1
|
2345 |
has wrong sign), \verb|ppp| is the current relative primal
|
alpar@1
|
2346 |
infeasibility (cf. (2.10)):
|
alpar@1
|
2347 |
$$\frac{\|Ax^{(k)}-b\|}{1+\|b\|},\eqno(2.14)$$
|
alpar@1
|
2348 |
\verb|ddd| is the current relative dual infeasibility (cf. (2.11)):
|
alpar@1
|
2349 |
$$\frac{\|A^T\pi^{(k)}+\lambda^{(k)}-c\|}{1+\|c\|},\eqno(2.15)$$
|
alpar@1
|
2350 |
\verb|ggg| is the current primal-dual gap (cf. (2.12)):
|
alpar@1
|
2351 |
$$\frac{|c^Tx^{(k)}-b^T\pi^{(k)}|}{1+|c^Tx^{(k)}|},\eqno(2.16)$$
|
alpar@1
|
2352 |
and $[x^{(k)},\pi^{(k)},\lambda^{(k)}]$ is the current point on $k$-th
|
alpar@1
|
2353 |
iteration, $k=0,1,2,\dots$\ . Note that all solution components are
|
alpar@1
|
2354 |
internally scaled, so information sent to the terminal is suitable only
|
alpar@1
|
2355 |
for visual inspection.
|
alpar@1
|
2356 |
|
alpar@1
|
2357 |
\subsubsection*{Control parameters}
|
alpar@1
|
2358 |
|
alpar@1
|
2359 |
This paragraph describes all control parameters currently used in the
|
alpar@1
|
2360 |
interior-point solver. Symbolic names of control parameters are names of
|
alpar@1
|
2361 |
corresponding members in the structure \verb|glp_iptcp|.
|
alpar@1
|
2362 |
|
alpar@1
|
2363 |
\medskip
|
alpar@1
|
2364 |
|
alpar@1
|
2365 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
2366 |
\multicolumn{2}{@{}l}{{\tt int msg\_lev} (default: {\tt GLP\_MSG\_ALL})}
|
alpar@1
|
2367 |
\\
|
alpar@1
|
2368 |
&Message level for terminal output:\\
|
alpar@1
|
2369 |
&\verb|GLP_MSG_OFF|---no output;\\
|
alpar@1
|
2370 |
&\verb|GLP_MSG_ERR|---error and warning messages only;\\
|
alpar@1
|
2371 |
&\verb|GLP_MSG_ON |---normal output;\\
|
alpar@1
|
2372 |
&\verb|GLP_MSG_ALL|---full output (including informational messages).
|
alpar@1
|
2373 |
\\
|
alpar@1
|
2374 |
\end{tabular}
|
alpar@1
|
2375 |
|
alpar@1
|
2376 |
\medskip
|
alpar@1
|
2377 |
|
alpar@1
|
2378 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
2379 |
\multicolumn{2}{@{}l}{{\tt int ord\_alg} (default: {\tt GLP\_ORD\_AMD})}
|
alpar@1
|
2380 |
\\
|
alpar@1
|
2381 |
&Ordering algorithm used prior to Cholesky factorization:\\
|
alpar@1
|
2382 |
&\verb|GLP_ORD_NONE |---use natural (original) ordering;\\
|
alpar@1
|
2383 |
&\verb|GLP_ORD_QMD |---quotient minimum degree (QMD);\\
|
alpar@1
|
2384 |
&\verb|GLP_ORD_AMD |---approximate minimum degree (AMD);\\
|
alpar@1
|
2385 |
&\verb|GLP_ORD_SYMAMD|---approximate minimum degree (SYMAMD).\\
|
alpar@1
|
2386 |
\end{tabular}
|
alpar@1
|
2387 |
|
alpar@1
|
2388 |
\subsubsection*{Example}
|
alpar@1
|
2389 |
|
alpar@1
|
2390 |
The following main program reads LP problem instance in fixed MPS
|
alpar@1
|
2391 |
format from file \verb|25fv47.mps|,\footnote{This instance in fixed MPS
|
alpar@1
|
2392 |
format can be found in the Netlib LP collection; see
|
alpar@1
|
2393 |
{\tt ftp://ftp.netlib.org/lp/data/}.} solves it with the interior-point
|
alpar@1
|
2394 |
solver, and writes the solution to file \verb|25fv47.txt|.
|
alpar@1
|
2395 |
|
alpar@1
|
2396 |
\begin{footnotesize}
|
alpar@1
|
2397 |
\begin{verbatim}
|
alpar@1
|
2398 |
/* iptsamp.c */
|
alpar@1
|
2399 |
|
alpar@1
|
2400 |
#include <stdio.h>
|
alpar@1
|
2401 |
#include <stdlib.h>
|
alpar@1
|
2402 |
#include <glpk.h>
|
alpar@1
|
2403 |
|
alpar@1
|
2404 |
int main(void)
|
alpar@1
|
2405 |
{ glp_prob *P;
|
alpar@1
|
2406 |
P = glp_create_prob();
|
alpar@1
|
2407 |
glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps");
|
alpar@1
|
2408 |
glp_interior(P, NULL);
|
alpar@1
|
2409 |
glp_print_ipt(P, "25fv47.txt");
|
alpar@1
|
2410 |
glp_delete_prob(P);
|
alpar@1
|
2411 |
return 0;
|
alpar@1
|
2412 |
}
|
alpar@1
|
2413 |
|
alpar@1
|
2414 |
/* eof */
|
alpar@1
|
2415 |
\end{verbatim}
|
alpar@1
|
2416 |
\end{footnotesize}
|
alpar@1
|
2417 |
|
alpar@1
|
2418 |
\noindent
|
alpar@1
|
2419 |
Below here is shown the terminal output from this example program.
|
alpar@1
|
2420 |
|
alpar@1
|
2421 |
\begin{footnotesize}
|
alpar@1
|
2422 |
\begin{verbatim}
|
alpar@1
|
2423 |
Reading problem data from `25fv47.mps'...
|
alpar@1
|
2424 |
Problem: 25FV47
|
alpar@1
|
2425 |
Objective: R0000
|
alpar@1
|
2426 |
822 rows, 1571 columns, 11127 non-zeros
|
alpar@1
|
2427 |
6919 records were read
|
alpar@1
|
2428 |
Original LP has 822 row(s), 1571 column(s), and 11127 non-zero(s)
|
alpar@1
|
2429 |
Working LP has 821 row(s), 1876 column(s), and 10705 non-zero(s)
|
alpar@1
|
2430 |
Matrix A has 10705 non-zeros
|
alpar@1
|
2431 |
Matrix S = A*A' has 11895 non-zeros (upper triangle)
|
alpar@1
|
2432 |
Minimal degree ordering...
|
alpar@1
|
2433 |
Computing Cholesky factorization S = L'*L...
|
alpar@1
|
2434 |
Matrix L has 35411 non-zeros
|
alpar@1
|
2435 |
Guessing initial point...
|
alpar@1
|
2436 |
Optimization begins...
|
alpar@1
|
2437 |
0: obj = 1.823377629e+05; rpi = 1.3e+01; rdi = 1.4e+01; gap = 9.3e-01
|
alpar@1
|
2438 |
1: obj = 9.260045192e+04; rpi = 5.3e+00; rdi = 5.6e+00; gap = 6.8e+00
|
alpar@1
|
2439 |
2: obj = 3.596999742e+04; rpi = 1.5e+00; rdi = 1.2e+00; gap = 1.8e+01
|
alpar@1
|
2440 |
3: obj = 1.989627568e+04; rpi = 4.7e-01; rdi = 3.0e-01; gap = 1.9e+01
|
alpar@1
|
2441 |
4: obj = 1.430215557e+04; rpi = 1.1e-01; rdi = 8.6e-02; gap = 1.4e+01
|
alpar@1
|
2442 |
5: obj = 1.155716505e+04; rpi = 2.3e-02; rdi = 2.4e-02; gap = 6.8e+00
|
alpar@1
|
2443 |
6: obj = 9.660273208e+03; rpi = 6.7e-03; rdi = 4.6e-03; gap = 3.9e+00
|
alpar@1
|
2444 |
7: obj = 8.694348283e+03; rpi = 3.7e-03; rdi = 1.7e-03; gap = 2.0e+00
|
alpar@1
|
2445 |
8: obj = 8.019543639e+03; rpi = 2.4e-03; rdi = 3.9e-04; gap = 1.0e+00
|
alpar@1
|
2446 |
9: obj = 7.122676293e+03; rpi = 1.2e-03; rdi = 1.5e-04; gap = 6.6e-01
|
alpar@1
|
2447 |
10: obj = 6.514534518e+03; rpi = 6.1e-04; rdi = 4.3e-05; gap = 4.1e-01
|
alpar@1
|
2448 |
11: obj = 6.361572203e+03; rpi = 4.8e-04; rdi = 2.2e-05; gap = 3.0e-01
|
alpar@1
|
2449 |
12: obj = 6.203355508e+03; rpi = 3.2e-04; rdi = 1.7e-05; gap = 2.6e-01
|
alpar@1
|
2450 |
13: obj = 6.032943411e+03; rpi = 2.0e-04; rdi = 9.3e-06; gap = 2.1e-01
|
alpar@1
|
2451 |
14: obj = 5.796553021e+03; rpi = 9.8e-05; rdi = 3.2e-06; gap = 1.0e-01
|
alpar@1
|
2452 |
15: obj = 5.667032431e+03; rpi = 4.4e-05; rdi = 1.1e-06; gap = 5.6e-02
|
alpar@1
|
2453 |
16: obj = 5.613911867e+03; rpi = 2.5e-05; rdi = 4.1e-07; gap = 3.5e-02
|
alpar@1
|
2454 |
17: obj = 5.560572626e+03; rpi = 9.9e-06; rdi = 2.3e-07; gap = 2.1e-02
|
alpar@1
|
2455 |
18: obj = 5.537276001e+03; rpi = 5.5e-06; rdi = 8.4e-08; gap = 1.1e-02
|
alpar@1
|
2456 |
19: obj = 5.522746942e+03; rpi = 2.2e-06; rdi = 4.0e-08; gap = 6.7e-03
|
alpar@1
|
2457 |
20: obj = 5.509956679e+03; rpi = 7.5e-07; rdi = 1.8e-08; gap = 2.9e-03
|
alpar@1
|
2458 |
21: obj = 5.504571733e+03; rpi = 1.6e-07; rdi = 5.8e-09; gap = 1.1e-03
|
alpar@1
|
2459 |
22: obj = 5.502576367e+03; rpi = 3.4e-08; rdi = 1.0e-09; gap = 2.5e-04
|
alpar@1
|
2460 |
23: obj = 5.502057119e+03; rpi = 8.1e-09; rdi = 3.0e-10; gap = 7.7e-05
|
alpar@1
|
2461 |
24: obj = 5.501885996e+03; rpi = 9.4e-10; rdi = 1.2e-10; gap = 2.4e-05
|
alpar@1
|
2462 |
25: obj = 5.501852464e+03; rpi = 1.4e-10; rdi = 1.2e-11; gap = 3.0e-06
|
alpar@1
|
2463 |
26: obj = 5.501846549e+03; rpi = 1.4e-11; rdi = 1.2e-12; gap = 3.0e-07
|
alpar@1
|
2464 |
27: obj = 5.501845954e+03; rpi = 1.4e-12; rdi = 1.2e-13; gap = 3.0e-08
|
alpar@1
|
2465 |
28: obj = 5.501845895e+03; rpi = 1.5e-13; rdi = 1.2e-14; gap = 3.0e-09
|
alpar@1
|
2466 |
OPTIMAL SOLUTION FOUND
|
alpar@1
|
2467 |
Writing interior-point solution to `25fv47.txt'...
|
alpar@1
|
2468 |
\end{verbatim}
|
alpar@1
|
2469 |
\end{footnotesize}
|
alpar@1
|
2470 |
|
alpar@1
|
2471 |
\subsection{glp\_init\_iptcp---initialize interior-point solver control
|
alpar@1
|
2472 |
parameters}
|
alpar@1
|
2473 |
|
alpar@1
|
2474 |
\subsubsection*{Synopsis}
|
alpar@1
|
2475 |
|
alpar@1
|
2476 |
\begin{verbatim}
|
alpar@1
|
2477 |
int glp_init_iptcp(glp_iptcp *parm);
|
alpar@1
|
2478 |
\end{verbatim}
|
alpar@1
|
2479 |
|
alpar@1
|
2480 |
\subsubsection*{Description}
|
alpar@1
|
2481 |
|
alpar@1
|
2482 |
The routine \verb|glp_init_iptcp| initializes control parameters, which
|
alpar@1
|
2483 |
are used by the interior-point solver, with default values.
|
alpar@1
|
2484 |
|
alpar@1
|
2485 |
Default values of the control parameters are stored in the structure
|
alpar@1
|
2486 |
\verb|glp_iptcp|, which the parameter \verb|parm| points to.
|
alpar@1
|
2487 |
|
alpar@1
|
2488 |
\subsection{glp\_ipt\_status---determine solution status}
|
alpar@1
|
2489 |
|
alpar@1
|
2490 |
\subsubsection*{Synopsis}
|
alpar@1
|
2491 |
|
alpar@1
|
2492 |
\begin{verbatim}
|
alpar@1
|
2493 |
int glp_ipt_status(glp_prob *lp);
|
alpar@1
|
2494 |
\end{verbatim}
|
alpar@1
|
2495 |
|
alpar@1
|
2496 |
\subsubsection*{Returns}
|
alpar@1
|
2497 |
|
alpar@1
|
2498 |
The routine \verb|glp_ipt_status| reports the status of a solution
|
alpar@1
|
2499 |
found by the interior-point solver as follows:
|
alpar@1
|
2500 |
|
alpar@1
|
2501 |
\begin{tabular}{@{}p{25mm}p{91.3mm}@{}}
|
alpar@1
|
2502 |
\verb|GLP_UNDEF| & interior-point solution is undefined. \\
|
alpar@1
|
2503 |
\verb|GLP_OPT| & interior-point solution is optimal. \\
|
alpar@1
|
2504 |
\verb|GLP_INFEAS|& interior-point solution is infeasible. \\
|
alpar@1
|
2505 |
\verb|GLP_NOFEAS|& no feasible primal-dual solution exists.\\
|
alpar@1
|
2506 |
\end{tabular}
|
alpar@1
|
2507 |
|
alpar@1
|
2508 |
\subsection{glp\_ipt\_obj\_val---retrieve objective value}
|
alpar@1
|
2509 |
|
alpar@1
|
2510 |
\subsubsection*{Synopsis}
|
alpar@1
|
2511 |
|
alpar@1
|
2512 |
\begin{verbatim}
|
alpar@1
|
2513 |
double glp_ipt_obj_val(glp_prob *lp);
|
alpar@1
|
2514 |
\end{verbatim}
|
alpar@1
|
2515 |
|
alpar@1
|
2516 |
\subsubsection*{Returns}
|
alpar@1
|
2517 |
|
alpar@1
|
2518 |
The routine \verb|glp_ipt_obj_val| returns value of the objective
|
alpar@1
|
2519 |
function for interior-point solution.
|
alpar@1
|
2520 |
|
alpar@1
|
2521 |
\subsection{glp\_ipt\_row\_prim---retrieve row primal value}
|
alpar@1
|
2522 |
|
alpar@1
|
2523 |
\subsubsection*{Synopsis}
|
alpar@1
|
2524 |
|
alpar@1
|
2525 |
\begin{verbatim}
|
alpar@1
|
2526 |
double glp_ipt_row_prim(glp_prob *lp, int i);
|
alpar@1
|
2527 |
\end{verbatim}
|
alpar@1
|
2528 |
|
alpar@1
|
2529 |
\subsubsection*{Returns}
|
alpar@1
|
2530 |
|
alpar@1
|
2531 |
The routine \verb|glp_ipt_row_prim| returns primal value of the
|
alpar@1
|
2532 |
auxiliary variable associated with \verb|i|-th row.
|
alpar@1
|
2533 |
|
alpar@1
|
2534 |
\newpage
|
alpar@1
|
2535 |
|
alpar@1
|
2536 |
\subsection{glp\_ipt\_row\_dual---retrieve row dual value}
|
alpar@1
|
2537 |
|
alpar@1
|
2538 |
\subsubsection*{Synopsis}
|
alpar@1
|
2539 |
|
alpar@1
|
2540 |
\begin{verbatim}
|
alpar@1
|
2541 |
double glp_ipt_row_dual(glp_prob *lp, int i);
|
alpar@1
|
2542 |
\end{verbatim}
|
alpar@1
|
2543 |
|
alpar@1
|
2544 |
\subsubsection*{Returns}
|
alpar@1
|
2545 |
|
alpar@1
|
2546 |
The routine \verb|glp_ipt_row_dual| returns dual value (i.e. reduced
|
alpar@1
|
2547 |
cost) of the auxiliary variable associated with \verb|i|-th row.
|
alpar@1
|
2548 |
|
alpar@1
|
2549 |
\subsection{glp\_ipt\_col\_prim---retrieve column primal value}
|
alpar@1
|
2550 |
|
alpar@1
|
2551 |
\subsubsection*{Synopsis}
|
alpar@1
|
2552 |
|
alpar@1
|
2553 |
\begin{verbatim}
|
alpar@1
|
2554 |
double glp_ipt_col_prim(glp_prob *lp, int j);
|
alpar@1
|
2555 |
\end{verbatim}
|
alpar@1
|
2556 |
|
alpar@1
|
2557 |
\subsubsection*{Returns}
|
alpar@1
|
2558 |
|
alpar@1
|
2559 |
The routine \verb|glp_ipt_col_prim| returns primal value of the
|
alpar@1
|
2560 |
structural variable associated with \verb|j|-th column.
|
alpar@1
|
2561 |
|
alpar@1
|
2562 |
\subsection{glp\_ipt\_col\_dual---retrieve column dual value}
|
alpar@1
|
2563 |
|
alpar@1
|
2564 |
\subsubsection*{Synopsis}
|
alpar@1
|
2565 |
|
alpar@1
|
2566 |
\begin{verbatim}
|
alpar@1
|
2567 |
double glp_ipt_col_dual(glp_prob *lp, int j);
|
alpar@1
|
2568 |
\end{verbatim}
|
alpar@1
|
2569 |
|
alpar@1
|
2570 |
\subsubsection*{Returns}
|
alpar@1
|
2571 |
|
alpar@1
|
2572 |
The routine \verb|glp_ipt_col_dual| returns dual value (i.e. reduced
|
alpar@1
|
2573 |
cost) of the structural variable associated with \verb|j|-th column.
|
alpar@1
|
2574 |
|
alpar@1
|
2575 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
alpar@1
|
2576 |
|
alpar@1
|
2577 |
\newpage
|
alpar@1
|
2578 |
|
alpar@1
|
2579 |
\section{Mixed integer programming routines}
|
alpar@1
|
2580 |
|
alpar@1
|
2581 |
\subsection{glp\_set\_col\_kind---set (change) column kind}
|
alpar@1
|
2582 |
|
alpar@1
|
2583 |
\subsubsection*{Synopsis}
|
alpar@1
|
2584 |
|
alpar@1
|
2585 |
\begin{verbatim}
|
alpar@1
|
2586 |
void glp_set_col_kind(glp_prob *mip, int j, int kind);
|
alpar@1
|
2587 |
\end{verbatim}
|
alpar@1
|
2588 |
|
alpar@1
|
2589 |
\subsubsection*{Description}
|
alpar@1
|
2590 |
|
alpar@1
|
2591 |
The routine \verb|glp_set_col_kind| sets (changes) the kind of
|
alpar@1
|
2592 |
\verb|j|-th column (structural variable) as specified by the parameter
|
alpar@1
|
2593 |
\verb|kind|:
|
alpar@1
|
2594 |
|
alpar@1
|
2595 |
\begin{tabular}{@{}ll}
|
alpar@1
|
2596 |
\verb|GLP_CV| & continuous variable; \\
|
alpar@1
|
2597 |
\verb|GLP_IV| & integer variable; \\
|
alpar@1
|
2598 |
\verb|GLP_BV| & binary variable. \\
|
alpar@1
|
2599 |
\end{tabular}
|
alpar@1
|
2600 |
|
alpar@1
|
2601 |
%If a column is set to \verb|GLP_IV|, its bounds must be exact integer
|
alpar@1
|
2602 |
%numbers with no tolerance, such that the condition
|
alpar@1
|
2603 |
%\verb|bnd == floor(bnd)| would hold.
|
alpar@1
|
2604 |
|
alpar@1
|
2605 |
Setting a column to \verb|GLP_BV| has the same effect as if it were
|
alpar@1
|
2606 |
set to \verb|GLP_IV|, its lower bound were set 0, and its upper bound
|
alpar@1
|
2607 |
were set to 1.
|
alpar@1
|
2608 |
|
alpar@1
|
2609 |
\subsection{glp\_get\_col\_kind---retrieve column kind}
|
alpar@1
|
2610 |
|
alpar@1
|
2611 |
\subsubsection*{Synopsis}
|
alpar@1
|
2612 |
|
alpar@1
|
2613 |
\begin{verbatim}
|
alpar@1
|
2614 |
int glp_get_col_kind(glp_prob *mip, int j);
|
alpar@1
|
2615 |
\end{verbatim}
|
alpar@1
|
2616 |
|
alpar@1
|
2617 |
\subsubsection*{Returns}
|
alpar@1
|
2618 |
|
alpar@1
|
2619 |
The routine \verb|glp_get_col_kind| returns the kind of \verb|j|-th
|
alpar@1
|
2620 |
column (structural variable) as follows:
|
alpar@1
|
2621 |
|
alpar@1
|
2622 |
\begin{tabular}{@{}ll}
|
alpar@1
|
2623 |
\verb|GLP_CV| & continuous variable; \\
|
alpar@1
|
2624 |
\verb|GLP_IV| & integer variable; \\
|
alpar@1
|
2625 |
\verb|GLP_BV| & binary variable. \\
|
alpar@1
|
2626 |
\end{tabular}
|
alpar@1
|
2627 |
|
alpar@1
|
2628 |
\subsection{glp\_get\_num\_int---retrieve number of integer columns}
|
alpar@1
|
2629 |
|
alpar@1
|
2630 |
\subsubsection*{Synopsis}
|
alpar@1
|
2631 |
|
alpar@1
|
2632 |
\begin{verbatim}
|
alpar@1
|
2633 |
int glp_get_num_int(glp_prob *mip);
|
alpar@1
|
2634 |
\end{verbatim}
|
alpar@1
|
2635 |
|
alpar@1
|
2636 |
\subsubsection*{Returns}
|
alpar@1
|
2637 |
|
alpar@1
|
2638 |
The routine \verb|glp_get_num_int| returns the number of columns
|
alpar@1
|
2639 |
(structural variables), which are marked as integer. Note that this
|
alpar@1
|
2640 |
number {\it does} include binary columns.
|
alpar@1
|
2641 |
|
alpar@1
|
2642 |
\subsection{glp\_get\_num\_bin---retrieve number of binary columns}
|
alpar@1
|
2643 |
|
alpar@1
|
2644 |
\subsubsection*{Synopsis}
|
alpar@1
|
2645 |
|
alpar@1
|
2646 |
\begin{verbatim}
|
alpar@1
|
2647 |
int glp_get_num_bin(glp_prob *mip);
|
alpar@1
|
2648 |
\end{verbatim}
|
alpar@1
|
2649 |
|
alpar@1
|
2650 |
\subsubsection*{Returns}
|
alpar@1
|
2651 |
|
alpar@1
|
2652 |
The routine \verb|glp_get_num_bin| returns the number of columns
|
alpar@1
|
2653 |
(structural variables), which are marked as integer and whose lower
|
alpar@1
|
2654 |
bound is zero and upper bound is one.
|
alpar@1
|
2655 |
|
alpar@1
|
2656 |
\subsection{glp\_intopt---solve MIP problem with the branch-and-cut
|
alpar@1
|
2657 |
method}
|
alpar@1
|
2658 |
|
alpar@1
|
2659 |
\subsubsection*{Synopsis}
|
alpar@1
|
2660 |
|
alpar@1
|
2661 |
\begin{verbatim}
|
alpar@1
|
2662 |
int glp_intopt(glp_prob *mip, const glp_iocp *parm);
|
alpar@1
|
2663 |
\end{verbatim}
|
alpar@1
|
2664 |
|
alpar@1
|
2665 |
\subsubsection*{Description}
|
alpar@1
|
2666 |
|
alpar@1
|
2667 |
The routine \verb|glp_intopt| is a driver to the MIP solver based on
|
alpar@1
|
2668 |
the branch-and-cut method, which is a hybrid of branch-and-bound and
|
alpar@1
|
2669 |
cutting plane methods.
|
alpar@1
|
2670 |
|
alpar@1
|
2671 |
If the presolver is disabled (see paragraph ``Control parameters''
|
alpar@1
|
2672 |
below), on entry to the routine \verb|glp_intopt| the problem object,
|
alpar@1
|
2673 |
which the parameter \verb|mip| points to, should contain optimal
|
alpar@1
|
2674 |
solution to LP relaxation (it can be obtained, for example, with the
|
alpar@1
|
2675 |
routine \verb|glp_simplex|). Otherwise, if the presolver is enabled, it
|
alpar@1
|
2676 |
is not necessary.
|
alpar@1
|
2677 |
|
alpar@1
|
2678 |
The MIP solver has a set of control parameters. Values of the control
|
alpar@1
|
2679 |
parameters can be passed in the structure \verb|glp_iocp|, which the
|
alpar@1
|
2680 |
parameter \verb|parm| points to. For detailed description of this
|
alpar@1
|
2681 |
structure see paragraph ``Control parameters'' below. Before specifying
|
alpar@1
|
2682 |
some control parameters the application program should initialize the
|
alpar@1
|
2683 |
structure \verb|glp_iocp| by default values of all control parameters
|
alpar@1
|
2684 |
using the routine \verb|glp_init_iocp| (see the next subsection). This
|
alpar@1
|
2685 |
is needed for backward compatibility, because in the future there may
|
alpar@1
|
2686 |
appear new members in the structure \verb|glp_iocp|.
|
alpar@1
|
2687 |
|
alpar@1
|
2688 |
The parameter \verb|parm| can be specified as \verb|NULL|, in which case
|
alpar@1
|
2689 |
the solver uses default settings.
|
alpar@1
|
2690 |
|
alpar@1
|
2691 |
Note that the GLPK branch-and-cut solver is not perfect, so it is unable
|
alpar@1
|
2692 |
to solve hard or very large scale MIP instances for a reasonable time.
|
alpar@1
|
2693 |
|
alpar@1
|
2694 |
\subsubsection*{Returns}
|
alpar@1
|
2695 |
|
alpar@1
|
2696 |
\def\arraystretch{1}
|
alpar@1
|
2697 |
|
alpar@1
|
2698 |
\begin{tabular}{@{}p{25mm}p{97.3mm}@{}}
|
alpar@1
|
2699 |
0 & The MIP problem instance has been successfully solved. (This code
|
alpar@1
|
2700 |
does {\it not} necessarily mean that the solver has found optimal
|
alpar@1
|
2701 |
solution. It only means that the solution process was successful.) \\
|
alpar@1
|
2702 |
\verb|GLP_EBOUND| & Unable to start the search, because some
|
alpar@1
|
2703 |
double-bounded variables have incorrect bounds or some integer variables
|
alpar@1
|
2704 |
have non-integer (fractional) bounds.\\
|
alpar@1
|
2705 |
\verb|GLP_EROOT| & Unable to start the search, because optimal basis for
|
alpar@1
|
2706 |
initial LP relaxation is not provided. (This code may appear only if the
|
alpar@1
|
2707 |
presolver is disabled.)\\
|
alpar@1
|
2708 |
\verb|GLP_ENOPFS| & Unable to start the search, because LP relaxation
|
alpar@1
|
2709 |
of the MIP problem instance has no primal feasible solution. (This code
|
alpar@1
|
2710 |
may appear only if the presolver is enabled.)\\
|
alpar@1
|
2711 |
\verb|GLP_ENODFS| & Unable to start the search, because LP relaxation
|
alpar@1
|
2712 |
of the MIP problem instance has no dual feasible solution. In other
|
alpar@1
|
2713 |
word, this code means that if the LP relaxation has at least one primal
|
alpar@1
|
2714 |
feasible solution, its optimal solution is unbounded, so if the MIP
|
alpar@1
|
2715 |
problem has at least one integer feasible solution, its (integer)
|
alpar@1
|
2716 |
optimal solution is also unbounded. (This code may appear only if the
|
alpar@1
|
2717 |
presolver is enabled.)\\
|
alpar@1
|
2718 |
\verb|GLP_EFAIL| & The search was prematurely terminated due to the
|
alpar@1
|
2719 |
solver failure.\\
|
alpar@1
|
2720 |
\verb|GLP_EMIPGAP| & The search was prematurely terminated, because the
|
alpar@1
|
2721 |
relative mip gap tolerance has been reached.\\
|
alpar@1
|
2722 |
\verb|GLP_ETMLIM| & The search was prematurely terminated, because the
|
alpar@1
|
2723 |
time limit has been exceeded.\\
|
alpar@1
|
2724 |
\verb|GLP_ESTOP| & The search was prematurely terminated by application.
|
alpar@1
|
2725 |
(This code may appear only if the advanced solver interface is used.)\\
|
alpar@1
|
2726 |
\end{tabular}
|
alpar@1
|
2727 |
|
alpar@1
|
2728 |
\subsubsection*{Built-in MIP presolver}
|
alpar@1
|
2729 |
|
alpar@1
|
2730 |
The branch-and-cut solver has {\it built-in MIP presolver}. It is
|
alpar@1
|
2731 |
a subprogram that transforms the original MIP problem specified in the
|
alpar@1
|
2732 |
problem object to an equivalent MIP problem, which may be easier for
|
alpar@1
|
2733 |
solving with the branch-and-cut method than the original one. For
|
alpar@1
|
2734 |
example, the presolver can remove redundant constraints and variables,
|
alpar@1
|
2735 |
whose optimal values are known, perform bound and coefficient reduction,
|
alpar@1
|
2736 |
etc. Once the transformed MIP problem has been solved, the presolver
|
alpar@1
|
2737 |
transforms its solution back to corresponding solution of the original
|
alpar@1
|
2738 |
problem.
|
alpar@1
|
2739 |
|
alpar@1
|
2740 |
Presolving is an optional feature of the routine \verb|glp_intopt|, and
|
alpar@1
|
2741 |
by default it is disabled. In order to enable the MIP presolver, the
|
alpar@1
|
2742 |
control parameter \verb|presolve| should be set to \verb|GLP_ON| (see
|
alpar@1
|
2743 |
paragraph ``Control parameters'' below).
|
alpar@1
|
2744 |
|
alpar@1
|
2745 |
\subsubsection*{Advanced solver interface}
|
alpar@1
|
2746 |
|
alpar@1
|
2747 |
The routine \verb|glp_intopt| allows the user to control the
|
alpar@1
|
2748 |
branch-and-cut search by passing to the solver a user-defined callback
|
alpar@1
|
2749 |
routine. For more details see Chapter ``Branch-and-Cut API Routines''.
|
alpar@1
|
2750 |
|
alpar@1
|
2751 |
\subsubsection*{Terminal output}
|
alpar@1
|
2752 |
|
alpar@1
|
2753 |
Solving a MIP problem may take a long time, so the solver reports some
|
alpar@1
|
2754 |
information about best known solutions, which is sent to the terminal.
|
alpar@1
|
2755 |
This information has the following format:
|
alpar@1
|
2756 |
|
alpar@1
|
2757 |
\begin{verbatim}
|
alpar@1
|
2758 |
+nnn: mip = xxx <rho> yyy gap (ppp; qqq)
|
alpar@1
|
2759 |
\end{verbatim}
|
alpar@1
|
2760 |
|
alpar@1
|
2761 |
\noindent
|
alpar@1
|
2762 |
where: `\verb|nnn|' is the simplex iteration number; `\verb|xxx|' is a
|
alpar@1
|
2763 |
value of the objective function for the best known integer feasible
|
alpar@1
|
2764 |
solution (if no integer feasible solution has been found yet,
|
alpar@1
|
2765 |
`\verb|xxx|' is the text `\verb|not found yet|'); `\verb|rho|' is the
|
alpar@1
|
2766 |
string `\verb|>=|' (in case of minimization) or `\verb|<=|' (in case of
|
alpar@1
|
2767 |
maximization); `\verb|yyy|' is a global bound for exact integer optimum
|
alpar@1
|
2768 |
(i.e. the exact integer optimum is always in the range from `\verb|xxx|'
|
alpar@1
|
2769 |
to `\verb|yyy|'); `\verb|gap|' is the relative mip gap, in percents,
|
alpar@1
|
2770 |
computed as $gap=|xxx-yyy|/(|xxx|+{\tt DBL\_EPSILON})\cdot 100\%$ (if
|
alpar@1
|
2771 |
$gap$ is greater than $999.9\%$, it is not printed); `\verb|ppp|' is the
|
alpar@1
|
2772 |
number of subproblems in the active list, `\verb|qqq|' is the number of
|
alpar@1
|
2773 |
subproblems which have been already fathomed and therefore removed from
|
alpar@1
|
2774 |
the branch-and-bound search tree.
|
alpar@1
|
2775 |
|
alpar@1
|
2776 |
\subsubsection{Control parameters}
|
alpar@1
|
2777 |
|
alpar@1
|
2778 |
This paragraph describes all control parameters currently used in the
|
alpar@1
|
2779 |
MIP solver. Symbolic names of control parameters are names of
|
alpar@1
|
2780 |
corresponding members in the structure \verb|glp_iocp|.
|
alpar@1
|
2781 |
|
alpar@1
|
2782 |
\medskip
|
alpar@1
|
2783 |
|
alpar@1
|
2784 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
2785 |
\multicolumn{2}{@{}l}{{\tt int msg\_lev} (default: {\tt GLP\_MSG\_ALL})}
|
alpar@1
|
2786 |
\\
|
alpar@1
|
2787 |
&Message level for terminal output:\\
|
alpar@1
|
2788 |
&\verb|GLP_MSG_OFF|---no output;\\
|
alpar@1
|
2789 |
&\verb|GLP_MSG_ERR|---error and warning messages only;\\
|
alpar@1
|
2790 |
&\verb|GLP_MSG_ON |---normal output;\\
|
alpar@1
|
2791 |
&\verb|GLP_MSG_ALL|---full output (including informational messages).
|
alpar@1
|
2792 |
\\
|
alpar@1
|
2793 |
\end{tabular}
|
alpar@1
|
2794 |
|
alpar@1
|
2795 |
\medskip
|
alpar@1
|
2796 |
|
alpar@1
|
2797 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
2798 |
\multicolumn{2}{@{}l}{{\tt int br\_tech} (default: {\tt GLP\_BR\_DTH})}
|
alpar@1
|
2799 |
\\
|
alpar@1
|
2800 |
&Branching technique option:\\
|
alpar@1
|
2801 |
&\verb|GLP_BR_FFV|---first fractional variable;\\
|
alpar@1
|
2802 |
&\verb|GLP_BR_LFV|---last fractional variable;\\
|
alpar@1
|
2803 |
&\verb|GLP_BR_MFV|---most fractional variable;\\
|
alpar@1
|
2804 |
&\verb|GLP_BR_DTH|---heuristic by Driebeck and Tomlin;\\
|
alpar@1
|
2805 |
&\verb|GLP_BR_PCH|---hybrid pseudocost heuristic.\\
|
alpar@1
|
2806 |
\end{tabular}
|
alpar@1
|
2807 |
|
alpar@1
|
2808 |
\medskip
|
alpar@1
|
2809 |
|
alpar@1
|
2810 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
2811 |
\multicolumn{2}{@{}l}{{\tt int bt\_tech} (default: {\tt GLP\_BT\_BLB})}
|
alpar@1
|
2812 |
\\
|
alpar@1
|
2813 |
&Backtracking technique option:\\
|
alpar@1
|
2814 |
&\verb|GLP_BT_DFS|---depth first search;\\
|
alpar@1
|
2815 |
&\verb|GLP_BT_BFS|---breadth first search;\\
|
alpar@1
|
2816 |
&\verb|GLP_BT_BLB|---best local bound;\\
|
alpar@1
|
2817 |
&\verb|GLP_BT_BPH|---best projection heuristic.\\
|
alpar@1
|
2818 |
\end{tabular}
|
alpar@1
|
2819 |
|
alpar@1
|
2820 |
\medskip
|
alpar@1
|
2821 |
|
alpar@1
|
2822 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
2823 |
\multicolumn{2}{@{}l}{{\tt int pp\_tech} (default: {\tt GLP\_PP\_ALL})}
|
alpar@1
|
2824 |
\\
|
alpar@1
|
2825 |
&Preprocessing technique option:\\
|
alpar@1
|
2826 |
&\verb|GLP_PP_NONE|---disable preprocessing;\\
|
alpar@1
|
2827 |
&\verb|GLP_PP_ROOT|---perform preprocessing only on the root level;\\
|
alpar@1
|
2828 |
&\verb|GLP_PP_ALL |---perform preprocessing on all levels.\\
|
alpar@1
|
2829 |
\end{tabular}
|
alpar@1
|
2830 |
|
alpar@1
|
2831 |
\medskip
|
alpar@1
|
2832 |
|
alpar@1
|
2833 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
2834 |
\multicolumn{2}{@{}l}{{\tt int fp\_heur} (default: {\tt GLP\_OFF})}
|
alpar@1
|
2835 |
\\
|
alpar@1
|
2836 |
&Feasibility pump heuristic option:\\
|
alpar@1
|
2837 |
&\verb|GLP_ON |---enable applying the feasibility pump heuristic;\\
|
alpar@1
|
2838 |
&\verb|GLP_OFF|---disable applying the feasibility pump heuristic.\\
|
alpar@1
|
2839 |
\end{tabular}
|
alpar@1
|
2840 |
|
alpar@1
|
2841 |
\medskip
|
alpar@1
|
2842 |
|
alpar@1
|
2843 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
2844 |
\multicolumn{2}{@{}l}{{\tt int gmi\_cuts} (default: {\tt GLP\_OFF})}\\
|
alpar@1
|
2845 |
&Gomory's mixed integer cut option:\\
|
alpar@1
|
2846 |
&\verb|GLP_ON |---enable generating Gomory's cuts;\\
|
alpar@1
|
2847 |
&\verb|GLP_OFF|---disable generating Gomory's cuts.\\
|
alpar@1
|
2848 |
\end{tabular}
|
alpar@1
|
2849 |
|
alpar@1
|
2850 |
\medskip
|
alpar@1
|
2851 |
|
alpar@1
|
2852 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
2853 |
\multicolumn{2}{@{}l}{{\tt int mir\_cuts} (default: {\tt GLP\_OFF})}\\
|
alpar@1
|
2854 |
&Mixed integer rounding (MIR) cut option:\\
|
alpar@1
|
2855 |
&\verb|GLP_ON |---enable generating MIR cuts;\\
|
alpar@1
|
2856 |
&\verb|GLP_OFF|---disable generating MIR cuts.\\
|
alpar@1
|
2857 |
\end{tabular}
|
alpar@1
|
2858 |
|
alpar@1
|
2859 |
\medskip
|
alpar@1
|
2860 |
|
alpar@1
|
2861 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
2862 |
\multicolumn{2}{@{}l}{{\tt int cov\_cuts} (default: {\tt GLP\_OFF})}\\
|
alpar@1
|
2863 |
&Mixed cover cut option:\\
|
alpar@1
|
2864 |
&\verb|GLP_ON |---enable generating mixed cover cuts;\\
|
alpar@1
|
2865 |
&\verb|GLP_OFF|---disable generating mixed cover cuts.\\
|
alpar@1
|
2866 |
\end{tabular}
|
alpar@1
|
2867 |
|
alpar@1
|
2868 |
\medskip
|
alpar@1
|
2869 |
|
alpar@1
|
2870 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
2871 |
\multicolumn{2}{@{}l}{{\tt int clq\_cuts} (default: {\tt GLP\_OFF})}\\
|
alpar@1
|
2872 |
&Clique cut option:\\
|
alpar@1
|
2873 |
&\verb|GLP_ON |---enable generating clique cuts;\\
|
alpar@1
|
2874 |
&\verb|GLP_OFF|---disable generating clique cuts.\\
|
alpar@1
|
2875 |
\end{tabular}
|
alpar@1
|
2876 |
|
alpar@1
|
2877 |
\medskip
|
alpar@1
|
2878 |
|
alpar@1
|
2879 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
2880 |
\multicolumn{2}{@{}l}{{\tt double tol\_int} (default: {\tt 1e-5})}\\
|
alpar@1
|
2881 |
&Absolute tolerance used to check if optimal solution to the current LP
|
alpar@1
|
2882 |
relaxation is integer feasible. (Do not change this parameter without
|
alpar@1
|
2883 |
detailed understanding its purpose.)\\
|
alpar@1
|
2884 |
\end{tabular}
|
alpar@1
|
2885 |
|
alpar@1
|
2886 |
\medskip
|
alpar@1
|
2887 |
|
alpar@1
|
2888 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
2889 |
\multicolumn{2}{@{}l}{{\tt double tol\_obj} (default: {\tt 1e-7})}\\
|
alpar@1
|
2890 |
&Relative tolerance used to check if the objective value in optimal
|
alpar@1
|
2891 |
solution to the current LP relaxation is not better than in the best
|
alpar@1
|
2892 |
known integer feasible solution. (Do not change this parameter without
|
alpar@1
|
2893 |
detailed understanding its purpose.)\\
|
alpar@1
|
2894 |
\end{tabular}
|
alpar@1
|
2895 |
|
alpar@1
|
2896 |
\medskip
|
alpar@1
|
2897 |
|
alpar@1
|
2898 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
2899 |
\multicolumn{2}{@{}l}{{\tt double mip\_gap} (default: {\tt 0.0})}\\
|
alpar@1
|
2900 |
&The relative mip gap tolerance. If the relative mip gap for currently
|
alpar@1
|
2901 |
known best integer feasible solution falls below this tolerance, the
|
alpar@1
|
2902 |
solver terminates the search. This allows obtainig suboptimal integer
|
alpar@1
|
2903 |
feasible solutions if solving the problem to optimality takes too long
|
alpar@1
|
2904 |
time.\\
|
alpar@1
|
2905 |
\end{tabular}
|
alpar@1
|
2906 |
|
alpar@1
|
2907 |
\medskip
|
alpar@1
|
2908 |
|
alpar@1
|
2909 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
2910 |
\multicolumn{2}{@{}l}{{\tt int tm\_lim} (default: {\tt INT\_MAX})}\\
|
alpar@1
|
2911 |
&Searching time limit, in milliseconds.\\
|
alpar@1
|
2912 |
\end{tabular}
|
alpar@1
|
2913 |
|
alpar@1
|
2914 |
\medskip
|
alpar@1
|
2915 |
|
alpar@1
|
2916 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
2917 |
\multicolumn{2}{@{}l}{{\tt int out\_frq} (default: {\tt 5000})}\\
|
alpar@1
|
2918 |
&Output frequency, in milliseconds. This parameter specifies how
|
alpar@1
|
2919 |
frequently the solver sends information about the solution process to
|
alpar@1
|
2920 |
the terminal.\\
|
alpar@1
|
2921 |
\end{tabular}
|
alpar@1
|
2922 |
|
alpar@1
|
2923 |
\medskip
|
alpar@1
|
2924 |
|
alpar@1
|
2925 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
2926 |
\multicolumn{2}{@{}l}{{\tt int out\_dly} (default: {\tt 10000})}\\
|
alpar@1
|
2927 |
&Output delay, in milliseconds. This parameter specifies how long the
|
alpar@1
|
2928 |
solver should delay sending information about solution of the current
|
alpar@1
|
2929 |
LP relaxation with the simplex method to the terminal.\\
|
alpar@1
|
2930 |
\end{tabular}
|
alpar@1
|
2931 |
|
alpar@1
|
2932 |
\medskip
|
alpar@1
|
2933 |
|
alpar@1
|
2934 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
2935 |
\multicolumn{2}{@{}l}
|
alpar@1
|
2936 |
{{\tt void (*cb\_func)(glp\_tree *tree, void *info)}
|
alpar@1
|
2937 |
(default: {\tt NULL})}\\
|
alpar@1
|
2938 |
&Entry point to the user-defined callback routine. \verb|NULL| means
|
alpar@1
|
2939 |
the advanced solver interface is not used. For more details see Chapter
|
alpar@1
|
2940 |
``Branch-and-Cut API Routines''.\\
|
alpar@1
|
2941 |
\end{tabular}
|
alpar@1
|
2942 |
|
alpar@1
|
2943 |
\medskip
|
alpar@1
|
2944 |
|
alpar@1
|
2945 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
2946 |
\multicolumn{2}{@{}l}{{\tt void *cb\_info} (default: {\tt NULL})}\\
|
alpar@1
|
2947 |
&Transit pointer passed to the routine \verb|cb_func| (see above).\\
|
alpar@1
|
2948 |
\end{tabular}
|
alpar@1
|
2949 |
|
alpar@1
|
2950 |
\medskip
|
alpar@1
|
2951 |
|
alpar@1
|
2952 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
2953 |
\multicolumn{2}{@{}l}{{\tt int cb\_size} (default: {\tt 0})}\\
|
alpar@1
|
2954 |
&The number of extra (up to 256) bytes allocated for each node of the
|
alpar@1
|
2955 |
branch-and-bound tree to store application-specific data. On creating
|
alpar@1
|
2956 |
a node these bytes are initialized by binary zeros.\\
|
alpar@1
|
2957 |
\end{tabular}
|
alpar@1
|
2958 |
|
alpar@1
|
2959 |
\medskip
|
alpar@1
|
2960 |
|
alpar@1
|
2961 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
2962 |
\multicolumn{2}{@{}l}{{\tt int presolve} (default: {\tt GLP\_OFF})}\\
|
alpar@1
|
2963 |
&MIP presolver option:\\
|
alpar@1
|
2964 |
&\verb|GLP_ON |---enable using the MIP presolver;\\
|
alpar@1
|
2965 |
&\verb|GLP_OFF|---disable using the MIP presolver.\\
|
alpar@1
|
2966 |
\end{tabular}
|
alpar@1
|
2967 |
|
alpar@1
|
2968 |
\medskip
|
alpar@1
|
2969 |
|
alpar@1
|
2970 |
\noindent\begin{tabular}{@{}p{17pt}@{}p{120.5mm}@{}}
|
alpar@1
|
2971 |
\multicolumn{2}{@{}l}{{\tt int binarize} (default: {\tt GLP\_OFF})}\\
|
alpar@1
|
2972 |
&Binarization option (used only if the presolver is enabled):\\
|
alpar@1
|
2973 |
&\verb|GLP_ON |---replace general integer variables by binary ones;\\
|
alpar@1
|
2974 |
&\verb|GLP_OFF|---do not use binarization.\\
|
alpar@1
|
2975 |
\end{tabular}
|
alpar@1
|
2976 |
|
alpar@1
|
2977 |
\subsection{glp\_init\_iocp---initialize integer optimizer control
|
alpar@1
|
2978 |
parameters}
|
alpar@1
|
2979 |
|
alpar@1
|
2980 |
\subsubsection*{Synopsis}
|
alpar@1
|
2981 |
|
alpar@1
|
2982 |
\begin{verbatim}
|
alpar@1
|
2983 |
void glp_init_iocp(glp_iocp *parm);
|
alpar@1
|
2984 |
\end{verbatim}
|
alpar@1
|
2985 |
|
alpar@1
|
2986 |
\subsubsection*{Description}
|
alpar@1
|
2987 |
|
alpar@1
|
2988 |
The routine \verb|glp_init_iocp| initializes control parameters, which
|
alpar@1
|
2989 |
are used by the branch-and-cut solver, with default values.
|
alpar@1
|
2990 |
|
alpar@1
|
2991 |
Default values of the control parameters are stored in a \verb|glp_iocp|
|
alpar@1
|
2992 |
structure, which the parameter \verb|parm| points to.
|
alpar@1
|
2993 |
|
alpar@1
|
2994 |
\subsection{glp\_mip\_status---determine status of MIP solution}
|
alpar@1
|
2995 |
|
alpar@1
|
2996 |
\subsubsection*{Synopsis}
|
alpar@1
|
2997 |
|
alpar@1
|
2998 |
\begin{verbatim}
|
alpar@1
|
2999 |
int glp_mip_status(glp_prob *mip);
|
alpar@1
|
3000 |
\end{verbatim}
|
alpar@1
|
3001 |
|
alpar@1
|
3002 |
\subsubsection*{Returns}
|
alpar@1
|
3003 |
|
alpar@1
|
3004 |
The routine \verb|glp_mip_status| reports the status of a MIP solution
|
alpar@1
|
3005 |
found by the MIP solver as follows:
|
alpar@1
|
3006 |
|
alpar@1
|
3007 |
\smallskip
|
alpar@1
|
3008 |
|
alpar@1
|
3009 |
\begin{tabular}{@{}p{25mm}p{91.3mm}@{}}
|
alpar@1
|
3010 |
\verb|GLP_UNDEF| & MIP solution is undefined. \\
|
alpar@1
|
3011 |
\verb|GLP_OPT| & MIP solution is integer optimal. \\
|
alpar@1
|
3012 |
\verb|GLP_FEAS| & MIP solution is integer feasible, however, its
|
alpar@1
|
3013 |
optimality (or non-optimality) has not been proven, perhaps due to
|
alpar@1
|
3014 |
premature termination of the search. \\
|
alpar@1
|
3015 |
\end{tabular}
|
alpar@1
|
3016 |
|
alpar@1
|
3017 |
\begin{tabular}{@{}p{25mm}p{91.3mm}@{}}
|
alpar@1
|
3018 |
\verb|GLP_NOFEAS| & problem has no integer feasible solution (proven by
|
alpar@1
|
3019 |
the solver). \\
|
alpar@1
|
3020 |
\end{tabular}
|
alpar@1
|
3021 |
|
alpar@1
|
3022 |
\subsection{glp\_mip\_obj\_val---retrieve objective value}
|
alpar@1
|
3023 |
|
alpar@1
|
3024 |
\subsubsection*{Synopsis}
|
alpar@1
|
3025 |
|
alpar@1
|
3026 |
\begin{verbatim}
|
alpar@1
|
3027 |
double glp_mip_obj_val(glp_prob *mip);
|
alpar@1
|
3028 |
\end{verbatim}
|
alpar@1
|
3029 |
|
alpar@1
|
3030 |
\subsubsection*{Returns}
|
alpar@1
|
3031 |
|
alpar@1
|
3032 |
The routine \verb|glp_mip_obj_val| returns value of the objective
|
alpar@1
|
3033 |
function for MIP solution.
|
alpar@1
|
3034 |
|
alpar@1
|
3035 |
\subsection{glp\_mip\_row\_val---retrieve row value}
|
alpar@1
|
3036 |
|
alpar@1
|
3037 |
\subsubsection*{Synopsis}
|
alpar@1
|
3038 |
|
alpar@1
|
3039 |
\begin{verbatim}
|
alpar@1
|
3040 |
double glp_mip_row_val(glp_prob *mip, int i);
|
alpar@1
|
3041 |
\end{verbatim}
|
alpar@1
|
3042 |
|
alpar@1
|
3043 |
\subsubsection*{Returns}
|
alpar@1
|
3044 |
|
alpar@1
|
3045 |
The routine \verb|glp_mip_row_val| returns value of the auxiliary
|
alpar@1
|
3046 |
variable associated with \verb|i|-th row for MIP solution.
|
alpar@1
|
3047 |
|
alpar@1
|
3048 |
\subsection{glp\_mip\_col\_val---retrieve column value}
|
alpar@1
|
3049 |
|
alpar@1
|
3050 |
\subsubsection*{Synopsis}
|
alpar@1
|
3051 |
|
alpar@1
|
3052 |
\begin{verbatim}
|
alpar@1
|
3053 |
double glp_mip_col_val(glp_prob *mip, int j);
|
alpar@1
|
3054 |
\end{verbatim}
|
alpar@1
|
3055 |
|
alpar@1
|
3056 |
\subsubsection*{Returns}
|
alpar@1
|
3057 |
|
alpar@1
|
3058 |
The routine \verb|glp_mip_col_val| returns value of the structural
|
alpar@1
|
3059 |
variable associated with \verb|j|-th column for MIP solution.
|
alpar@1
|
3060 |
|
alpar@1
|
3061 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
alpar@1
|
3062 |
|
alpar@1
|
3063 |
\newpage
|
alpar@1
|
3064 |
|
alpar@1
|
3065 |
\section{Additional routines}
|
alpar@1
|
3066 |
|
alpar@1
|
3067 |
\subsection{lpx\_check\_kkt---check Karush-Kuhn-Tucker optimality
|
alpar@1
|
3068 |
conditions}
|
alpar@1
|
3069 |
|
alpar@1
|
3070 |
\subsubsection*{Synopsis}
|
alpar@1
|
3071 |
|
alpar@1
|
3072 |
\begin{verbatim}
|
alpar@1
|
3073 |
void lpx_check_kkt(glp_prob *lp, int scaled, LPXKKT *kkt);
|
alpar@1
|
3074 |
\end{verbatim}
|
alpar@1
|
3075 |
|
alpar@1
|
3076 |
\subsubsection*{Description}
|
alpar@1
|
3077 |
|
alpar@1
|
3078 |
The routine \verb|lpx_check_kkt| checks Karush-Kuhn-Tucker optimality
|
alpar@1
|
3079 |
conditions for basic solution. It is assumed that both primal and dual
|
alpar@1
|
3080 |
components of basic solution are valid.
|
alpar@1
|
3081 |
|
alpar@1
|
3082 |
If the parameter \verb|scaled| is zero, the optimality conditions are
|
alpar@1
|
3083 |
checked for the original, unscaled LP problem. Otherwise, if the
|
alpar@1
|
3084 |
parameter \verb|scaled| is non-zero, the routine checks the conditions
|
alpar@1
|
3085 |
for an internally scaled LP problem.
|
alpar@1
|
3086 |
|
alpar@1
|
3087 |
The parameter \verb|kkt| is a pointer to the structure \verb|LPXKKT|,
|
alpar@1
|
3088 |
to which the routine stores results of the check. Members of this
|
alpar@1
|
3089 |
structure are shown in the table below.
|
alpar@1
|
3090 |
|
alpar@1
|
3091 |
\begin{table}[h]
|
alpar@1
|
3092 |
\begin{center}
|
alpar@1
|
3093 |
\begin{tabular}{@{}c|l|l@{}}
|
alpar@1
|
3094 |
Condition & Member & Comment \\
|
alpar@1
|
3095 |
\hline
|
alpar@1
|
3096 |
(KKT.PE) & \verb|pe_ae_max| &
|
alpar@1
|
3097 |
Largest absolute error \\
|
alpar@1
|
3098 |
& \verb|pe_ae_row| &
|
alpar@1
|
3099 |
Number of row with largest absolute error \\
|
alpar@1
|
3100 |
& \verb|pe_re_max| &
|
alpar@1
|
3101 |
Largest relative error \\
|
alpar@1
|
3102 |
& \verb|pe_re_row| &
|
alpar@1
|
3103 |
Number of row with largest relative error \\
|
alpar@1
|
3104 |
& \verb|pe_quality| &
|
alpar@1
|
3105 |
Quality of primal solution \\
|
alpar@1
|
3106 |
\hline
|
alpar@1
|
3107 |
(KKT.PB) & \verb|pb_ae_max| &
|
alpar@1
|
3108 |
Largest absolute error \\
|
alpar@1
|
3109 |
& \verb|pb_ae_ind| &
|
alpar@1
|
3110 |
Number of variable with largest absolute error \\
|
alpar@1
|
3111 |
& \verb|pb_re_max| &
|
alpar@1
|
3112 |
Largest relative error \\
|
alpar@1
|
3113 |
& \verb|pb_re_ind| &
|
alpar@1
|
3114 |
Number of variable with largest relative error \\
|
alpar@1
|
3115 |
& \verb|pb_quality| &
|
alpar@1
|
3116 |
Quality of primal feasibility \\
|
alpar@1
|
3117 |
\hline
|
alpar@1
|
3118 |
(KKT.DE) & \verb|de_ae_max| &
|
alpar@1
|
3119 |
Largest absolute error \\
|
alpar@1
|
3120 |
& \verb|de_ae_col| &
|
alpar@1
|
3121 |
Number of column with largest absolute error \\
|
alpar@1
|
3122 |
& \verb|de_re_max| &
|
alpar@1
|
3123 |
Largest relative error \\
|
alpar@1
|
3124 |
& \verb|de_re_col| &
|
alpar@1
|
3125 |
Number of column with largest relative error \\
|
alpar@1
|
3126 |
& \verb|de_quality| &
|
alpar@1
|
3127 |
Quality of dual solution \\
|
alpar@1
|
3128 |
\hline
|
alpar@1
|
3129 |
(KKT.DB) & \verb|db_ae_max| &
|
alpar@1
|
3130 |
Largest absolute error \\
|
alpar@1
|
3131 |
& \verb|db_ae_ind| &
|
alpar@1
|
3132 |
Number of variable with largest absolute error \\
|
alpar@1
|
3133 |
& \verb|db_re_max| &
|
alpar@1
|
3134 |
Largest relative error \\
|
alpar@1
|
3135 |
& \verb|db_re_ind| &
|
alpar@1
|
3136 |
Number of variable with largest relative error \\
|
alpar@1
|
3137 |
& \verb|db_quality| &
|
alpar@1
|
3138 |
Quality of dual feasibility \\
|
alpar@1
|
3139 |
\end{tabular}
|
alpar@1
|
3140 |
\end{center}
|
alpar@1
|
3141 |
\end{table}
|
alpar@1
|
3142 |
|
alpar@1
|
3143 |
The routine performs all computations using only components of the
|
alpar@1
|
3144 |
given LP problem and the current basic solution.
|
alpar@1
|
3145 |
|
alpar@1
|
3146 |
\subsubsection*{Background}
|
alpar@1
|
3147 |
|
alpar@1
|
3148 |
The first condition checked by the routine is:
|
alpar@1
|
3149 |
$$x_R - A x_S = 0, \eqno{\rm (KKT.PE)}$$
|
alpar@1
|
3150 |
where $x_R$ is the subvector of auxiliary variables (rows), $x_S$ is the
|
alpar@1
|
3151 |
subvector of structural variables (columns), $A$ is the constraint
|
alpar@1
|
3152 |
matrix. This condition expresses the requirement that all primal
|
alpar@1
|
3153 |
variables must satisfy to the system of equality constraints of the
|
alpar@1
|
3154 |
original LP problem. In case of exact arithmetic this condition would be
|
alpar@1
|
3155 |
satisfied for any basic solution; however, in case of inexact
|
alpar@1
|
3156 |
(floating-point) arithmetic, this condition shows how accurate the
|
alpar@1
|
3157 |
primal basic solution is, that depends on accuracy of a representation
|
alpar@1
|
3158 |
of the basis matrix used by the simplex method routines.
|
alpar@1
|
3159 |
|
alpar@1
|
3160 |
The second condition checked by the routine is:
|
alpar@1
|
3161 |
$$l_k \leq x_k \leq u_k {\rm \ \ \ for\ all}\ k=1,\dots,m+n,
|
alpar@1
|
3162 |
\eqno{\rm (KKT.PB)}$$
|
alpar@1
|
3163 |
where $x_k$ is auxiliary ($1\leq k\leq m$) or structural
|
alpar@1
|
3164 |
($m+1\leq k\leq m+n$) variable, $l_k$ and $u_k$ are, respectively,
|
alpar@1
|
3165 |
lower and upper bounds of the variable $x_k$ (including cases of
|
alpar@1
|
3166 |
infinite bounds). This condition expresses the requirement that all
|
alpar@1
|
3167 |
primal variables must satisfy to bound constraints of the original LP
|
alpar@1
|
3168 |
problem. Since in case of basic solution all non-basic variables are
|
alpar@1
|
3169 |
placed on their bounds, actually the condition (KKT.PB) needs to be
|
alpar@1
|
3170 |
checked for basic variables only. If the primal basic solution has
|
alpar@1
|
3171 |
sufficient accuracy, this condition shows primal feasibility of the
|
alpar@1
|
3172 |
solution.
|
alpar@1
|
3173 |
|
alpar@1
|
3174 |
The third condition checked by the routine is:
|
alpar@1
|
3175 |
$${\rm grad}\;Z = c = (\tilde{A})^T \pi + d,$$
|
alpar@1
|
3176 |
where $Z$ is the objective function, $c$ is the vector of objective
|
alpar@1
|
3177 |
coefficients, $(\tilde{A})^T$ is a matrix transposed to the expanded
|
alpar@1
|
3178 |
constraint matrix $\tilde{A} = (I|-A)$, $\pi$ is a vector of Lagrange
|
alpar@1
|
3179 |
multipliers that correspond to equality constraints of the original LP
|
alpar@1
|
3180 |
problem, $d$ is a vector of Lagrange multipliers that correspond to
|
alpar@1
|
3181 |
bound constraints for all (auxiliary and structural) variables of the
|
alpar@1
|
3182 |
original LP problem. Geometrically the third condition expresses the
|
alpar@1
|
3183 |
requirement that the gradient of the objective function must belong to
|
alpar@1
|
3184 |
the orthogonal complement of a linear subspace defined by the equality
|
alpar@1
|
3185 |
and active bound constraints, i.e. that the gradient must be a linear
|
alpar@1
|
3186 |
combination of normals to the constraint planes, where Lagrange
|
alpar@1
|
3187 |
multipliers $\pi$ and $d$ are coefficients of that linear combination.
|
alpar@1
|
3188 |
|
alpar@1
|
3189 |
To eliminate the vector $\pi$ the third condition can be rewritten as:
|
alpar@1
|
3190 |
$$
|
alpar@1
|
3191 |
\left(\begin{array}{@{}c@{}}I \\ -A^T\end{array}\right) \pi =
|
alpar@1
|
3192 |
\left(\begin{array}{@{}c@{}}d_R \\ d_S\end{array}\right) +
|
alpar@1
|
3193 |
\left(\begin{array}{@{}c@{}}c_R \\ c_S\end{array}\right),
|
alpar@1
|
3194 |
$$
|
alpar@1
|
3195 |
or, equivalently:
|
alpar@1
|
3196 |
$$
|
alpar@1
|
3197 |
\begin{array}{r@{}c@{}c}
|
alpar@1
|
3198 |
\pi + d_R&\ =\ &c_R, \\
|
alpar@1
|
3199 |
-A^T\pi + d_S&\ =\ &c_S. \\
|
alpar@1
|
3200 |
\end{array}
|
alpar@1
|
3201 |
$$
|
alpar@1
|
3202 |
Then substituting the vector $\pi$ from the first equation into the
|
alpar@1
|
3203 |
second one we have:
|
alpar@1
|
3204 |
$$A^T (d_R - c_R) + (d_S - c_S) = 0, \eqno{\rm (KKT.DE)}$$
|
alpar@1
|
3205 |
where $d_R$ is the subvector of reduced costs of auxiliary variables
|
alpar@1
|
3206 |
(rows), $d_S$ is the subvector of reduced costs of structural variables
|
alpar@1
|
3207 |
(columns), $c_R$ and $c_S$ are subvectors of objective coefficients at,
|
alpar@1
|
3208 |
respectively, auxiliary and structural variables, $A^T$ is a matrix
|
alpar@1
|
3209 |
transposed to the constraint matrix of the original LP problem. In case
|
alpar@1
|
3210 |
of exact arithmetic this condition would be satisfied for any basic
|
alpar@1
|
3211 |
solution; however, in case of inexact (floating-point) arithmetic, this
|
alpar@1
|
3212 |
condition shows how accurate the dual basic solution is, that depends on
|
alpar@1
|
3213 |
accuracy of a representation of the basis matrix used by the simplex
|
alpar@1
|
3214 |
method routines.
|
alpar@1
|
3215 |
|
alpar@1
|
3216 |
The last, fourth condition checked by the routine is (KKT.DB):
|
alpar@1
|
3217 |
|
alpar@1
|
3218 |
\medskip
|
alpar@1
|
3219 |
|
alpar@1
|
3220 |
\begin{tabular}{r@{}c@{}ll}
|
alpar@1
|
3221 |
&$\ d_k\ $& $=0,$&if $x_k$ is basic or free non-basic variable \\
|
alpar@1
|
3222 |
$0\leq$&$\ d_k\ $&$<+\infty$&if $x_k$ is non-basic on its lower
|
alpar@1
|
3223 |
(minimization) \\
|
alpar@1
|
3224 |
&&&or upper (maximization) bound \\
|
alpar@1
|
3225 |
$-\infty<$&$\ d_k\ $&$\leq 0$&if $x_k$ is non-basic on its upper
|
alpar@1
|
3226 |
(minimization) \\
|
alpar@1
|
3227 |
&&&or lower (maximization) bound \\
|
alpar@1
|
3228 |
$-\infty<$&$\ d_k\ $&$<+\infty$&if $x_k$ is non-basic fixed variable \\
|
alpar@1
|
3229 |
\end{tabular}
|
alpar@1
|
3230 |
|
alpar@1
|
3231 |
\medskip
|
alpar@1
|
3232 |
|
alpar@1
|
3233 |
\noindent
|
alpar@1
|
3234 |
for all $k=1,\dots,m+n$, where $d_k$ is a reduced cost (Lagrange
|
alpar@1
|
3235 |
multiplier) of auxiliary ($1\leq k\leq m$) or structural
|
alpar@1
|
3236 |
($m+1\leq k\leq m+n$) variable $x_k$. Geometrically this condition
|
alpar@1
|
3237 |
expresses the requirement that constraints of the original problem must
|
alpar@1
|
3238 |
"hold" the point preventing its movement along the anti-gradient (in
|
alpar@1
|
3239 |
case of minimization) or the gradient (in case of maximization) of the
|
alpar@1
|
3240 |
objective function. Since in case of basic solution reduced costs of
|
alpar@1
|
3241 |
all basic variables are placed on their (zero) bounds, actually the
|
alpar@1
|
3242 |
condition (KKT.DB) needs to be checked for non-basic variables only.
|
alpar@1
|
3243 |
If the dual basic solution has sufficient accuracy, this condition shows
|
alpar@1
|
3244 |
dual feasibility of the solution.
|
alpar@1
|
3245 |
|
alpar@1
|
3246 |
Should note that the complete set of Karush-Kuhn-Tucker optimality
|
alpar@1
|
3247 |
conditions also includes the fifth, so called complementary slackness
|
alpar@1
|
3248 |
condition, which expresses the requirement that at least either a primal
|
alpar@1
|
3249 |
variable $x_k$ or its dual counterpart $d_k$ must be on its bound for
|
alpar@1
|
3250 |
all $k=1,\dots,m+n$. However, being always satisfied by definition for
|
alpar@1
|
3251 |
any basic solution that condition is not checked by the routine.
|
alpar@1
|
3252 |
|
alpar@1
|
3253 |
To check the first condition (KKT.PE) the routine computes a vector of
|
alpar@1
|
3254 |
residuals:
|
alpar@1
|
3255 |
$$g = x_R - A x_S,$$
|
alpar@1
|
3256 |
determines component of this vector that correspond to largest absolute
|
alpar@1
|
3257 |
and relative errors:
|
alpar@1
|
3258 |
|
alpar@1
|
3259 |
\medskip
|
alpar@1
|
3260 |
|
alpar@1
|
3261 |
\hspace{30mm}
|
alpar@1
|
3262 |
\verb|pe_ae_max| $\displaystyle{= \max_{1\leq i\leq m}|g_i|}$,
|
alpar@1
|
3263 |
|
alpar@1
|
3264 |
\medskip
|
alpar@1
|
3265 |
|
alpar@1
|
3266 |
\hspace{30mm}
|
alpar@1
|
3267 |
\verb|pe_re_max| $\displaystyle{= \max_{1\leq i\leq m}
|
alpar@1
|
3268 |
\frac{|g_i|}{1+|(x_R)_i|}}$,
|
alpar@1
|
3269 |
|
alpar@1
|
3270 |
\medskip
|
alpar@1
|
3271 |
|
alpar@1
|
3272 |
\noindent
|
alpar@1
|
3273 |
and stores these quantities and corresponding row indices to the
|
alpar@1
|
3274 |
structure \verb|LPXKKT|.
|
alpar@1
|
3275 |
|
alpar@1
|
3276 |
To check the second condition (KKT.PB) the routine computes a vector
|
alpar@1
|
3277 |
of residuals:
|
alpar@1
|
3278 |
$$
|
alpar@1
|
3279 |
h_k = \left\{
|
alpar@1
|
3280 |
\begin{array}{ll}
|
alpar@1
|
3281 |
0, & {\rm if}\ l_k \leq x_k \leq u_k \\
|
alpar@1
|
3282 |
x_k - l_k, & {\rm if}\ x_k < l_k \\
|
alpar@1
|
3283 |
x_k - u_k, & {\rm if}\ x_k > u_k \\
|
alpar@1
|
3284 |
\end{array}
|
alpar@1
|
3285 |
\right.
|
alpar@1
|
3286 |
$$
|
alpar@1
|
3287 |
for all $k=1,\dots,m+n$, determines components of this vector that
|
alpar@1
|
3288 |
correspond to largest absolute and relative errors:
|
alpar@1
|
3289 |
|
alpar@1
|
3290 |
\medskip
|
alpar@1
|
3291 |
|
alpar@1
|
3292 |
\hspace{30mm}
|
alpar@1
|
3293 |
\verb|pb_ae_max| $\displaystyle{= \max_{1\leq k \leq m+n}|h_k|}$,
|
alpar@1
|
3294 |
|
alpar@1
|
3295 |
\medskip
|
alpar@1
|
3296 |
|
alpar@1
|
3297 |
\hspace{30mm}
|
alpar@1
|
3298 |
\verb|pb_re_max| $\displaystyle{= \max_{1\leq k \leq m+n}
|
alpar@1
|
3299 |
\frac{|h_k|}{1+|x_k|}}$,
|
alpar@1
|
3300 |
|
alpar@1
|
3301 |
\medskip
|
alpar@1
|
3302 |
|
alpar@1
|
3303 |
\noindent
|
alpar@1
|
3304 |
and stores these quantities and corresponding variable indices to the
|
alpar@1
|
3305 |
structure \verb|LPXKKT|.
|
alpar@1
|
3306 |
|
alpar@1
|
3307 |
To check the third condition (KKT.DE) the routine computes a vector of
|
alpar@1
|
3308 |
residuals:
|
alpar@1
|
3309 |
$$u = A^T (d_R - c_R) + (d_S - c_S),$$
|
alpar@1
|
3310 |
determines components of this vector that correspond to largest
|
alpar@1
|
3311 |
absolute and relative errors:
|
alpar@1
|
3312 |
|
alpar@1
|
3313 |
\medskip
|
alpar@1
|
3314 |
|
alpar@1
|
3315 |
\hspace{30mm}
|
alpar@1
|
3316 |
\verb|de_ae_max| $\displaystyle{= \max_{1\leq j\leq n}|u_j|}$,
|
alpar@1
|
3317 |
|
alpar@1
|
3318 |
\medskip
|
alpar@1
|
3319 |
|
alpar@1
|
3320 |
\hspace{30mm}
|
alpar@1
|
3321 |
\verb|de_re_max| $\displaystyle{= \max_{1\leq j\leq n}
|
alpar@1
|
3322 |
\frac{|u_j|}{1+|(d_S)_j - (c_S)_j|}}$,
|
alpar@1
|
3323 |
|
alpar@1
|
3324 |
\medskip
|
alpar@1
|
3325 |
|
alpar@1
|
3326 |
\noindent
|
alpar@1
|
3327 |
and stores these quantities and corresponding column indices to the
|
alpar@1
|
3328 |
structure \verb|LPXKKT|.
|
alpar@1
|
3329 |
|
alpar@1
|
3330 |
To check the fourth condition (KKT.DB) the routine computes a vector
|
alpar@1
|
3331 |
of residuals:
|
alpar@1
|
3332 |
|
alpar@1
|
3333 |
$$
|
alpar@1
|
3334 |
v_k = \left\{
|
alpar@1
|
3335 |
\begin{array}{ll}
|
alpar@1
|
3336 |
0, & {\rm if}\ d_k\ {\rm has\ correct\ sign} \\
|
alpar@1
|
3337 |
d_k, & {\rm if}\ d_k\ {\rm has\ wrong\ sign} \\
|
alpar@1
|
3338 |
\end{array}
|
alpar@1
|
3339 |
\right.
|
alpar@1
|
3340 |
$$
|
alpar@1
|
3341 |
for all $k=1,\dots,m+n$, determines components of this vector that
|
alpar@1
|
3342 |
correspond to largest absolute and relative errors:
|
alpar@1
|
3343 |
|
alpar@1
|
3344 |
\medskip
|
alpar@1
|
3345 |
|
alpar@1
|
3346 |
\hspace{30mm}
|
alpar@1
|
3347 |
\verb|db_ae_max| $\displaystyle{= \max_{1\leq k\leq m+n}|v_k|}$,
|
alpar@1
|
3348 |
|
alpar@1
|
3349 |
\medskip
|
alpar@1
|
3350 |
|
alpar@1
|
3351 |
\hspace{30mm}
|
alpar@1
|
3352 |
\verb|db_re_max| $\displaystyle{= \max_{1\leq k\leq m+n}
|
alpar@1
|
3353 |
\frac{|v_k|}{1+|d_k - c_k|}}$,
|
alpar@1
|
3354 |
|
alpar@1
|
3355 |
\medskip
|
alpar@1
|
3356 |
|
alpar@1
|
3357 |
\noindent
|
alpar@1
|
3358 |
and stores these quantities and corresponding variable indices to the
|
alpar@1
|
3359 |
structure \verb|LPXKKT|.
|
alpar@1
|
3360 |
|
alpar@1
|
3361 |
Using the relative errors for all the four conditions listed above the
|
alpar@1
|
3362 |
routine
|
alpar@1
|
3363 |
\verb|lpx_check_kkt| also estimates a "quality" of the basic solution
|
alpar@1
|
3364 |
from the standpoint of these conditions and stores corresponding
|
alpar@1
|
3365 |
quality indicators to the structure \verb|LPXKKT|:
|
alpar@1
|
3366 |
|
alpar@1
|
3367 |
\verb|pe_quality|---quality of primal solution;
|
alpar@1
|
3368 |
|
alpar@1
|
3369 |
\verb|pb_quality|---quality of primal feasibility;
|
alpar@1
|
3370 |
|
alpar@1
|
3371 |
\verb|de_quality|---quality of dual solution;
|
alpar@1
|
3372 |
|
alpar@1
|
3373 |
\verb|db_quality|---quality of dual feasibility.
|
alpar@1
|
3374 |
|
alpar@1
|
3375 |
Each of these indicators is assigned to one of the following four
|
alpar@1
|
3376 |
values:
|
alpar@1
|
3377 |
|
alpar@1
|
3378 |
\verb|'H'| means high quality,
|
alpar@1
|
3379 |
|
alpar@1
|
3380 |
\verb|'M'| means medium quality,
|
alpar@1
|
3381 |
|
alpar@1
|
3382 |
\verb|'L'| means low quality, or
|
alpar@1
|
3383 |
|
alpar@1
|
3384 |
\verb|'?'| means wrong or infeasible solution.
|
alpar@1
|
3385 |
|
alpar@1
|
3386 |
If all the indicators show high or medium quality (for an internally
|
alpar@1
|
3387 |
scaled LP problem, i.e. when the parameter \verb|scaled| in a call to
|
alpar@1
|
3388 |
the routine \verb|lpx_check_kkt| is non-zero), the user can be sure that
|
alpar@1
|
3389 |
the obtained basic solution is quite accurate.
|
alpar@1
|
3390 |
|
alpar@1
|
3391 |
If some of the indicators show low quality, the solution can still be
|
alpar@1
|
3392 |
considered as relevant, though an additional analysis is needed
|
alpar@1
|
3393 |
depending on which indicator shows low quality.
|
alpar@1
|
3394 |
|
alpar@1
|
3395 |
If the indicator \verb|pe_quality| is assigned to \verb|'?'|, the
|
alpar@1
|
3396 |
primal solution is wrong. If the indicator \verb|de_quality| is assigned
|
alpar@1
|
3397 |
to \verb|'?'|, the dual solution is wrong.
|
alpar@1
|
3398 |
|
alpar@1
|
3399 |
If the indicator \verb|db_quality| is assigned to \verb|'?'| while
|
alpar@1
|
3400 |
other indicators show a good quality, this means that the current
|
alpar@1
|
3401 |
basic solution being primal feasible is not dual feasible. Similarly,
|
alpar@1
|
3402 |
if the indicator \verb|pb_quality| is assigned to \verb|'?'| while
|
alpar@1
|
3403 |
other indicators are not, this means that the current basic solution
|
alpar@1
|
3404 |
being dual feasible is not primal feasible.
|
alpar@1
|
3405 |
|
alpar@1
|
3406 |
%* eof *%
|