summaryrefslogtreecommitdiff
path: root/glpk-5.0/doc/graphs.tex
diff options
context:
space:
mode:
Diffstat (limited to 'glpk-5.0/doc/graphs.tex')
-rw-r--r--glpk-5.0/doc/graphs.tex4180
1 files changed, 4180 insertions, 0 deletions
diff --git a/glpk-5.0/doc/graphs.tex b/glpk-5.0/doc/graphs.tex
new file mode 100644
index 0000000..9f953bd
--- /dev/null
+++ b/glpk-5.0/doc/graphs.tex
@@ -0,0 +1,4180 @@
+%* graphs.tex *%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% The GLPK package is part of the GNU Project released under the aegis
+% of GNU.
+%
+% Copyright (c) 2007-2020 Free Software Foundation, Inc.
+%
+% Author: Andrew Makhorin <mao@gnu.org>.
+%
+% Permission is granted to copy, distribute and/or modify this
+% document under the terms of the GNU Free Documentation License,
+% Version 1.3 or any later version published by the Free Software
+% Foundation.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% To make graphs.pdf from graphs.tex run the following two commands:
+% latex graphs.tex
+% dvipdfm -p letter graphs.dvi
+% Note: You need TeX Live 2010 or later version.
+
+\documentclass[11pt]{report}
+\usepackage{amssymb}
+\usepackage[dvipdfm,linktocpage,colorlinks,linkcolor=blue,
+urlcolor=blue]{hyperref}
+\usepackage{indentfirst}
+\usepackage{niceframe}
+\usepackage[all]{xy}
+
+% US Letter = 8.5 x 11 in
+\setlength{\textwidth}{6.5in}
+\setlength{\textheight}{9in}
+\setlength{\oddsidemargin}{0in}
+\setlength{\topmargin}{0in}
+\setlength{\headheight}{0in}
+\setlength{\headsep}{0in}
+%\setlength{\footskip}{0.5in}
+\setlength{\parindent}{16pt}
+\setlength{\parskip}{5pt}
+\setlength{\topsep}{0pt}
+\setlength{\partopsep}{0pt}
+%\setlength{\itemsep}{\parskip}
+%\setlength{\parsep}{0pt}
+%\setlength{\leftmargini}{\parindent}
+%\renewcommand{\labelitemi}{---}
+
+\newcommand{\Item}[1]{\parbox[t]{\parindent}{#1}}
+\def\para#1{\noindent{\bf#1}}
+\def\synopsis{\para{Synopsis}}
+\def\description{\para{Description}}
+\def\note{\para{Note}}
+\def\returns{\para{Returns}}
+
+\renewcommand\contentsname{\sf\bfseries Contents}
+\renewcommand\chaptername{\sf\bfseries Chapter}
+\renewcommand\appendixname{\sf\bfseries Appendix}
+
+\newenvironment{retlist}
+{ \def\arraystretch{1.5}
+ \noindent
+ \begin{tabular}{@{}p{1in}@{}p{5.5in}@{}}
+}
+{\end{tabular}}
+
+\begin{document}
+
+\thispagestyle{empty}
+
+\artdecoframe{
+
+\begin{center}
+
+\vspace*{1.5in}
+
+\begin{huge}
+\sf\bfseries GNU Linear Programming Kit
+\end{huge}
+
+\vspace{0.5in}
+
+\begin{LARGE}
+\sf Graph and Network Routines
+\end{LARGE}
+
+\vspace{0.5in}
+
+\begin{LARGE}
+\sf for GLPK Version 5.0
+\end{LARGE}
+
+\vspace{0.5in}
+\begin{Large}
+\sf (December 2020)
+\end{Large}
+\end{center}
+
+\vspace*{3.2in}
+}
+
+\newpage
+
+\vspace*{1in}
+
+\vfill
+
+\noindent
+The GLPK package is part of the GNU Project released under the aegis of
+GNU.
+
+\noindent
+Copyright \copyright{} 2007-2020 Free Software Foundation, Inc.
+
+\noindent
+Author: Andrew Makhorin $\langle$mao@gnu.org$\rangle$.
+
+\noindent
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+{\setlength{\parskip}{0pt}\tableofcontents}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Basic Graph API Routines}
+
+\section{Graph program object}
+
+In GLPK the base program object used to represent graphs and networks
+is a directed graph (digraph).
+
+Formally, {\it digraph} (or simply, {\it graph}) is a pair $G=(V,A)$,
+where $V$ is a set of {\it vertices}, and $A$ is a set
+{\it arcs}.\footnote{$A$ may be a multiset.} Each arc $a\in A$ is an
+ordered pair of vertices $a=(x,y)$, where $x\in V$ is called {\it tail
+vertex} of arc $a$, and $y\in V$ is called its {\it head vertex}.
+
+Representation of a graph in the program includes three structs defined
+by typedef in the header \verb|glpk.h|:
+
+%\vspace*{-8pt}
+
+%\begin{itemize}
+\Item{---}\verb|glp_graph|, which represents the graph in a whole,
+
+\Item{---}\verb|glp_vertex|, which represents a vertex of the graph, and
+
+\Item{---}\verb|glp_arc|, which represents an arc of the graph.
+%\end{itemize}
+
+%\vspace*{-8pt}
+
+All these three structs are ``semi-opaque'', i.e. the application
+program can directly access their fields through pointers, however,
+changing the fields directly is not allowed --- all changes should be
+performed only with appropriate GLPK API routines.
+
+\newenvironment{comment}
+{\addtolength{\leftskip}{16pt}\noindent}
+{\par\addtolength{\leftskip}{-16pt}}
+
+\subsection{Structure glp\_graph}
+
+%\para{\bf glp\_graph.}
+The struct \verb|glp_graph| has the following fields available to the
+application program.
+
+\noindent
+\verb|char *name;|
+
+\begin{comment}Symbolic name assigned to the graph. It is a pointer to
+a null terminated character string of length from 1 to 255 characters.
+If no name is assigned to the graph, this field contains \verb|NULL|.
+\end{comment}
+
+\noindent
+\verb|int nv;|
+
+\begin{comment}The number of vertices in the graph, $nv\geq 0$.
+\end{comment}
+
+\noindent
+\verb|int na;|
+
+\begin{comment}The number of arcs in the graph, $na\geq 0$.
+\end{comment}
+
+\newpage
+
+\noindent
+\verb|glp_vertex **v;|
+
+\begin{comment}Pointer to an array containing the list of vertices.
+Element $v[0]$ is not used. Element $v[i]$, $1\leq i\leq nv$, is a
+pointer to $i$-th vertex of the graph. Note that on adding new vertices
+to the graph the field $v$ may be altered due to reallocation. However,
+pointers $v[i]$ are not changed while corresponding vertices exist in
+the graph.
+\end{comment}
+
+\noindent
+\verb|int v_size;|
+
+\begin{comment}Size of vertex data blocks, in bytes,
+$0\leq v\_size\leq 256$. (See also the field \verb|data| in the struct
+\verb|glp_vertex|.)
+\end{comment}
+
+\noindent
+\verb|int a_size;|
+
+\begin{comment}Size of arc data blocks, in bytes,
+$0\leq v\_size\leq 256$. (See also the field \verb|data| in the struct
+\verb|glp_arc|.)
+\end{comment}
+
+\subsection{Structure glp\_vertex}
+
+%\para{\bf glp\_vertex.}
+The struct \verb|glp_vertex| has the following fields available to the
+application program.
+
+\noindent
+\verb|int i;|
+
+\begin{comment}Ordinal number of the vertex, $1\leq i\leq nv$. Note
+that element $v[i]$ in the struct \verb|glp_graph| points to the vertex,
+whose ordinal number is $i$.
+\end{comment}
+
+\noindent
+\verb|char *name;|
+
+\begin{comment}Symbolic name assigned to the vertex. It is a pointer to
+a null terminated character string of length from 1 to 255 characters.
+If no name is assigned to the vertex, this field contains \verb|NULL|.
+\end{comment}
+
+\noindent
+\verb|void *data;|
+
+\begin{comment}Pointer to a data block associated with the vertex. This
+data block is automatically allocated on creating a new vertex and freed
+on deleting the vertex. If $v\_size=0$, the block is not allocated, and
+this field contains \verb|NULL|.
+\end{comment}
+
+\noindent
+\verb|void *temp;|
+
+\begin{comment}Working pointer, which may be used freely for any
+purposes. The application program can change this field directly.
+\end{comment}
+
+\noindent
+\verb|glp_arc *in;|
+
+\begin{comment}Pointer to the (unordered) list of incoming arcs. If the
+vertex has no incoming arcs, this field contains \verb|NULL|.
+\end{comment}
+
+\noindent
+\verb|glp_arc *out;|
+
+\begin{comment}Pointer to the (unordered) list of outgoing arcs. If the
+vertex has no outgoing arcs, this field contains \verb|NULL|.
+\end{comment}
+
+\subsection{Structure glp\_arc}
+
+%\para{\bf glp\_arc.}
+The struct \verb|glp_arc| has the following fields available to the
+application program.
+
+\noindent
+\verb|glp_vertex *tail;|
+
+\begin{comment}Pointer to a vertex, which is tail endpoint of the arc.
+\end{comment}
+
+\newpage
+
+\noindent
+\verb|glp_vertex *head;|
+
+\begin{comment}Pointer to a vertex, which is head endpoint of the arc.
+\end{comment}
+
+%\newpage
+
+\noindent
+\verb|void *data;|
+
+\begin{comment}Pointer to a data block associated with the arc. This
+data block is automatically allocated on creating a new arc and freed on
+deleting the arc. If $v\_size=0$, the block is not allocated, and this
+field contains \verb|NULL|.
+\end{comment}
+
+\noindent
+\verb|void *temp;|
+
+\begin{comment}Working pointer, which may be used freely for any
+purposes. The application program can change this field directly.
+\end{comment}
+
+\noindent
+\verb|glp_arc *t_next;|
+
+\begin{comment}Pointer to another arc, which has the same tail endpoint
+as this one. \verb|NULL| in this field indicates the end of the list of
+outgoing arcs.
+\end{comment}
+
+\noindent
+\verb|glp_arc *h_next;|
+
+\begin{comment}Pointer to another arc, which has the same head endpoint
+as this one. \verb|NULL| in this field indicates the end of the list of
+incoming arcs.
+\end{comment}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\setlength{\parskip}{4.6pt}
+
+\section{Graph creating and modifying routines}
+
+\subsection{glp\_create\_graph --- create graph}
+
+\synopsis
+
+\begin{verbatim}
+ glp_graph *glp_create_graph(int v_size, int a_size);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_create_graph| creates a new graph, which
+initially is empty, i.e. has no vertices and arcs.
+
+The parameter \verb|v_size| specifies the size of vertex data blocks,
+in bytes, $0\leq v\_size\leq 256$.
+
+The parameter \verb|a_size| specifies the size of arc data blocks, in
+bytes, $0\leq a\_size\leq 256$.
+
+\returns
+
+The routine returns a pointer to the graph object created.
+
+\subsection{glp\_set\_graph\_name --- assign (change) graph name}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_set_graph_name(glp_graph *G, const char *name);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_set_graph_name| assigns a symbolic name specified
+by the character string \verb|name| (1 to 255 chars) to the graph.
+
+If the parameter \verb|name| is \verb|NULL| or an empty string, the
+routine erases the existing symbolic name of the graph.
+
+\subsection{glp\_add\_vertices --- add new vertices to graph}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_add_vertices(glp_graph *G, int nadd);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_add_vertices| adds \verb|nadd| vertices to the
+specified graph. New vertices are always added to the end of the vertex
+list, so ordinal numbers of existing vertices remain unchanged. Note
+that this operation may change the field \verb|v| in the struct
+\verb|glp_graph| (pointer to the vertex array) due to reallocation.
+
+Being added each new vertex is isolated, i.e. has no incident arcs.
+
+If the size of vertex data blocks specified on creating the graph is
+non-zero, the routine also allocates a memory block of that size for
+each new vertex added, fills it by binary zeros, and stores a pointer
+to it in the field \verb|data| of the struct \verb|glp_vertex|.
+Otherwise, if the block size is zero, the field \verb|data| is set to
+\verb|NULL|.
+
+\returns
+
+The routine \verb|glp_add_vertices| returns the ordinal number of the
+first new vertex added to the graph.
+
+\setlength{\parskip}{5pt}
+
+\newpage
+
+\subsection{glp\_set\_vertex\_name --- assign (change) vertex name}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_set_vertex_name(glp_graph *G, int i, const char *name);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_set_vertex_name| assigns a given symbolic name
+(1 up to 255 characters) to \verb|i|-th vertex of the specified graph.
+
+If the parameter \verb|name| is \verb|NULL| or empty string, the
+routine erases an existing name of \verb|i|-th vertex.
+
+\subsection{glp\_add\_arc --- add new arc to graph}
+
+\synopsis
+
+\begin{verbatim}
+ glp_arc *glp_add_arc(glp_graph *G, int i, int j);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_add_arc| adds one new arc to the specified graph.
+
+The parameters \verb|i| and \verb|j| specify the ordinal numbers of,
+resp., tail and head endpoints (vertices) of the arc. Note that
+self-loops and multiple arcs are allowed.
+
+If the size of arc data blocks specified on creating the graph is
+non-zero, the routine also allocates a memory block of that size, fills
+it by binary zeros, and stores a pointer to it in the field \verb|data|
+of the struct \verb|glp_arc|. Otherwise, if the block size is zero, the
+field \verb|data| is set to \verb|NULL|.
+
+\subsection{glp\_del\_vertices --- delete vertices from graph}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_del_vertices(glp_graph *G, int ndel, const int num[]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_del_vertices| deletes vertices along with all
+incident arcs from the specified graph. Ordinal numbers of vertices to
+be deleted should be placed in locations \verb|num[1]|, \dots,
+\verb|num[ndel]|, \verb|ndel| $>0$.
+
+Note that deleting vertices involves changing ordinal numbers of other
+vertices remaining in the graph. New ordinal numbers of the remaining
+vertices are assigned under the assumption that the original order of
+vertices is not changed.
+
+%\newpage
+
+\subsection{glp\_del\_arc --- delete arc from graph}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_del_arc(glp_graph *G, glp_arc *a);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_del_arc| deletes an arc from the specified graph.
+The arc to be deleted must exist.
+
+\subsection{glp\_erase\_graph --- erase graph content}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_erase_graph(glp_graph *G, int v_size, int a_size);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_erase_graph| erases the content of the specified
+graph. The effect of this operation is the same as if the graph would
+be deleted with the routine \verb|glp_delete_graph| and then created
+anew with the routine \verb|glp_create_graph|, with exception that the
+pointer to the graph remains valid.
+
+The parameters \verb|v_size| and \verb|a_size| have the same meaning as
+for \verb|glp_create_graph|.
+
+\subsection{glp\_delete\_graph --- delete graph}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_delete_graph(glp_graph *G);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_delete_graph| deletes the specified graph and
+frees all the memory allocated to this program object.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Graph searching routines}
+
+\subsection{glp\_create\_v\_index --- create vertex name index}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_create_v_index(glp_graph *G);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_create_v_index| creates the name index for the
+specified graph. The name index is an auxiliary data structure, which
+is intended to quickly (i.e. for logarithmic time) find vertices by
+their names.
+
+This routine can be called at any time. If the name index already
+exists, the routine does nothing.
+
+\subsection{glp\_find\_vertex --- find vertex by its name}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_find_vertex(glp_graph *G, const char *name);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_find_vertex| returns the ordinal number of
+a vertex, which is assigned (by the routine \verb|glp_set_vertex_name|)
+the specified symbolic \verb|name|. If no such vertex exists, the
+routine returns 0.
+
+\subsection{glp\_delete\_v\_index --- delete vertex name index}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_delete_v_index(glp_graph *G);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_delete_v_index| deletes the name index previously
+created by the routine \verb|glp_create_v_index| and frees the memory
+allocated to this auxiliary data structure.
+
+This routine can be called at any time. If the name index does not
+exist, the routine does nothing.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Graph reading/writing routines}
+
+\subsection{glp\_read\_graph --- read graph from text file}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_read_graph(glp_graph *G, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_read_graph| reads a graph from a text file, whose
+name is specified by the parameter \verb|fname|. It is equivalent to
+
+\begin{verbatim}
+ glp_read_ccdata(G, -1, fname);
+\end{verbatim}
+
+Note that before reading data the current content of the graph object
+is completely erased with the routine \verb|glp_erase_graph|.
+
+\returns
+
+If the operation was successful, the routine returns zero. Otherwise
+it prints an error message and returns non-zero.
+
+\subsection{glp\_write\_graph --- write graph to text file}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_write_graph(glp_graph *G, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_write_graph| writes the graph to a text file,
+whose name is specified by the parameter \verb|fname|.
+It is equivalent to
+
+\begin{verbatim}
+ glp_write_ccdata(G, -1, fname);
+\end{verbatim}
+
+\returns
+
+If the operation was successful, the routine returns zero. Otherwise
+it prints an error message and returns non-zero.
+
+\subsection{glp\_read\_ccdata --- read graph from text file in DIMACS
+clique/coloring\\format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_read_ccdata(glp_graph *G, int v_wgt, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine {\tt glp\_read\_ccdata} reads a graph from a text file in
+DIMACS clique/coloring format. (Though this format is originally
+designed to represent data for the minimal vertex coloring and maximal
+clique problems, it may be used to represent general undirected and
+directed graphs, because the routine allows reading self-loops and
+multiple edges/arcs keeping the order of vertices specified for each
+edge/arc of the graph.)
+
+\newpage
+
+The parameter {\tt G} specifies the graph object to be read in. Note
+that before reading data the current content of the graph object is
+completely erased with the routine {\tt glp\_erase\_graph}.
+
+The parameter {\tt v\_wgt} specifies an offset of the field of type
+{\tt double} in the vertex data block, to which the routine stores the
+vertex weight. If {\tt v\_wgt} $<0$, the vertex weights are not stored.
+
+The character string {\tt fname} specifies the name of a text file to
+be read in. (If the file name ends with the suffix `\verb|.gz|', the
+file is assumed to be compressed, in which case the routine
+decompresses it ``on the fly''.)
+
+\returns
+
+If the operation was successful, the routine returns zero. Otherwise,
+it prints an error message and returns non-zero.
+
+\para{DIMACS clique/coloring format\footnote{This material is
+based on the paper ``Clique and Coloring Problems Graph Format'', which
+is publicly available at \url{http://dimacs.rutgers.edu/Challenges}.}}
+
+The DIMACS input file is a plain ASCII text file. It contains
+{\it lines} of several types described below. A line is terminated with
+an end-of-line character. Fields in each line are separated by at least
+one blank space. Each line begins with a one-character designator to
+identify the line type.
+
+Note that DIMACS requires all numerical quantities to be integers in
+the range $[-2^{31},2^{31}-1]$ while GLPK allows the quantities to be
+floating-point numbers.
+
+\para{Comment lines.} Comment lines give human-readable information
+about the file and are ignored by programs. Comment lines can appear
+anywhere in the file. Each comment line begins with a lower-case
+character \verb|c|.
+
+\begin{verbatim}
+ c This is a comment line
+\end{verbatim}
+
+\para{Problem line.} There is one problem line per data file.
+The problem line must appear before any node or edge descriptor lines.
+It has the following format:
+
+\begin{verbatim}
+ p edge NODES EDGES
+\end{verbatim}
+
+\noindent
+The lower-case letter \verb|p| signifies that this is a problem line.
+The four-character problem designator \verb|edge| identifies the file
+as containing data for the minimal vertex coloring or maximal clique
+problem. The \verb|NODES| field contains an integer value specifying
+the number of vertices in the graph. The \verb|EDGES| field contains an
+integer value specifying the number of edges (arcs) in the graph.
+
+\para{Vertex descriptors.} These lines give the weight assigned to
+a vertex of the graph. There is one vertex descriptor line for each
+vertex, with the following format. Vertices without a descriptor take
+on a default value of 1.
+
+\begin{verbatim}
+ n ID VALUE
+\end{verbatim}
+
+\noindent
+The lower-case character \verb|n| signifies that this is a vertex
+descriptor line. The \verb|ID| field gives a vertex identification
+number, an integer between 1 and $n$, where $n$ is the number of
+vertices in the graph. The \verb|VALUE| field gives a vertex weight,
+which can either positive or negative (or zero).
+
+\para{Edge descriptors.} There is one edge descriptor line for each
+edge (arc) of the graph, each with the following format:
+
+\begin{verbatim}
+ e I J
+\end{verbatim}
+
+\noindent
+The lower-case character \verb|e| signifies that this is an edge
+descriptor line. For an edge (arc) $(i,j)$ the fields \verb|I| and
+\verb|J| specify its endpoints.
+
+\newpage
+
+\para{Example.} The following undirected graph
+
+\bigskip
+
+\noindent\hfil
+\xymatrix %@C=32pt
+{&{v_1}\ar@{-}[ldd]\ar@{-}[dd]\ar@{-}[rd]\ar@{-}[rr]&&{v_2}\ar@{-}[ld]
+\ar@{-}[dd]\ar@{-}[rdd]&\\
+&&{v_7}\ar@{-}[ld]\ar@{-}[rd]&&\\
+{v_6}\ar@{-}[r]\ar@{-}[rdd]&{v_{10}}\ar@{-}[rr]\ar@{-}[rd]\ar@{-}[dd]&&
+{v_8}\ar@{-}[ld]\ar@{-}[dd]\ar@{-}[r]&{v_3}\ar@{-}[ldd]\\
+&&{v_9}\ar@{-}[ld]\ar@{-}[rd]&&\\
+&{v_5}\ar@{-}[rr]&&{v_4}&\\
+}
+
+\bigskip
+
+\noindent
+might be coded in DIMACS clique/coloring format as follows.
+
+\begin{footnotesize}
+\begin{verbatim}
+c sample.col
+c
+c This is an example of the vertex coloring problem data
+c in DIMACS format.
+c
+p edge 10 21
+c
+e 1 2
+e 1 6
+e 1 7
+e 1 10
+e 2 3
+e 2 7
+e 2 8
+e 3 4
+e 3 8
+e 4 5
+e 4 8
+e 4 9
+e 5 6
+e 5 9
+e 5 10
+e 6 10
+e 7 8
+e 7 10
+e 8 9
+e 8 10
+e 9 10
+c
+c eof
+\end{verbatim}
+\end{footnotesize}
+
+\newpage
+
+\subsection{glp\_write\_ccdata --- write graph to text file in DIMACS
+clique/coloring\\format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_write_ccdata(glp_graph *G, int v_wgt, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine {\tt glp\_write\_ccdata} writes the graph object specified
+by the parameter {\tt G} to a text file in DIMACS clique/coloring
+format. (Though this format is originally designed to represent data
+for the minimal vertex coloring and maximal clique problems, it may be
+used to represent general undirected and directed graphs, because the
+routine allows writing self-loops and multiple edges/arcs keeping the
+order of vertices specified for each edge/arc of the graph.)
+
+The parameter {\tt v\_wgt} specifies an offset of the field of type
+{\tt double} in the vertex data block, which contains the vertex
+weight. If {\tt v\_wgt} $<0$, it is assumed that the weight of each
+vertex is 1.
+
+The character string {\tt fname} specifies a name of the text file to
+be written out. (If the file name ends with suffix `\verb|.gz|', the
+file is assumed to be compressed, in which case the routine performs
+automatic compression on writing it.)
+
+\returns
+
+If the operation was successful, the routine returns zero. Otherwise,
+it prints an error message and returns non-zero.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Graph analysis routines}
+
+\subsection{glp\_weak\_comp --- find all weakly connected components of
+graph}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_weak_comp(glp_graph *G, int v_num);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_weak_comp| finds all weakly connected components
+of the specified graph.
+
+The parameter \verb|v_num| specifies an offset of the field of type
+\verb|int| in the vertex data block, to which the routine stores the
+number of a weakly connected component containing that vertex. If
+\verb|v_num| $<0$, no component numbers are stored.
+
+The components are numbered in arbitrary order from 1 to \verb|nc|,
+where \verb|nc| is the total number of components found,
+$0\leq$ \verb|nc| $\leq|V|$.
+
+\returns
+
+The routine returns \verb|nc|, the total number of components found.
+
+\subsection{glp\_strong\_comp --- find all strongly connected
+components of graph}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_strong_comp(glp_graph *G, int v_num);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_strong_comp| finds all strongly connected
+components of the specified graph.
+
+The parameter \verb|v_num| specifies an offset of the field of type
+\verb|int| in the vertex data block, to which the routine stores the
+number of a strongly connected component containing that vertex. If
+\verb|v_num| $<0$, no component numbers are stored.
+
+The components are numbered in arbitrary order from 1 to \verb|nc|,
+where \verb|nc| is the total number of components found,
+$0\leq$ \verb|nc| $\leq|V|$. However, the component numbering has the
+property that for every arc $(i\rightarrow j)$ in the graph the
+condition $num(i)\geq num(j)$ holds.
+
+\returns
+
+The routine returns \verb|nc|, the total number of components found.
+
+\para{References}
+
+I.~S.~Duff, J.~K.~Reid, Algorithm 529: Permutations to block triangular
+form, ACM Trans. on Math. Softw. 4 (1978), 189-92.
+
+\newpage
+
+\para{Example}
+
+The following program reads a graph from a plain text file
+`\verb|graph.txt|' and finds all its strongly connected components.
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+typedef struct { int num; } v_data;
+
+#define vertex(v) ((v_data *)((v)->data))
+
+int main(void)
+{ glp_graph *G;
+ int i, nc;
+ G = glp_create_graph(sizeof(v_data), 0);
+ glp_read_graph(G, "graph.txt");
+ nc = glp_strong_comp(G, offsetof(v_data, num));
+ printf("nc = %d\n", nc);
+ for (i = 1; i <= G->nv; i++)
+ printf("num[%d] = %d\n", i, vertex(G->v[i])->num);
+ glp_delete_graph(G);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+\noindent
+If the file `\verb|graph.txt|' contains the following graph:
+
+\medskip
+
+\noindent\hfil
+\xymatrix
+{1\ar[r]&2\ar[r]&3\ar[r]\ar[dd]&4\ar[dd]\\
+5\ar[u]&6\ar[l]\\
+7\ar[u]&&8\ar[lu]\ar[ll]\ar[r]&9\ar[r]&10\ar[r]\ar[d]&11\ar[d]\\
+12\ar[u]\ar[rru]\ar@/_/[rr]&&13\ar[ll]\ar[u]\ar[rr]&&14\ar[lu]&15\ar[l]
+\\
+}
+
+\medskip\medskip
+
+\noindent
+the program output may look like follows:
+
+\begin{footnotesize}
+\begin{verbatim}
+Reading graph from `graph.txt'...
+Graph has 15 vertices and 30 arcs
+31 lines were read
+nc = 4
+num[1] = 3
+num[2] = 3
+num[3] = 3
+num[4] = 2
+num[5] = 3
+num[6] = 3
+num[7] = 3
+num[8] = 3
+num[9] = 1
+num[10] = 1
+num[11] = 1
+num[12] = 4
+num[13] = 4
+num[14] = 1
+num[15] = 1
+\end{verbatim}
+\end{footnotesize}
+
+\subsection{glp\_top\_sort --- topological sorting of acyclic digraph}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_top_sort(glp_graph *G, int v_num);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_top_sort| performs topological sorting of
+vertices of the specified acyclic digraph.
+
+The parameter \verb|v_num| specifies an offset of the field of type
+\verb|int| in the vertex data block, to which the routine stores the
+vertex number assigned. If \verb|v_num| $<0$, vertex numbers are not
+stored.
+
+The vertices are numbered from 1 to $n$, where $n$ is the total number
+of vertices in the graph. The vertex numbering has the property that
+for every arc $(i\rightarrow j)$ in the graph the condition
+$num(i)<num(j)$ holds. Special case $num(i)=0$ means that vertex $i$ is
+not assigned a number, because the graph is {\it not} acyclic.
+
+\returns
+
+If the graph is acyclic and therefore all the vertices have been
+assigned numbers, the routine \verb|glp_top_sort| returns zero.
+Otherwise, if the graph is not acyclic, the routine returns the number
+of vertices which have not been numbered, i.e. for which $num(i)=0$.
+
+\para{Example}
+
+The following program reads a digraph from a plain text file
+`\verb|graph.txt|' and performs topological sorting of its vertices.
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+typedef struct { int num; } v_data;
+
+#define vertex(v) ((v_data *)((v)->data))
+
+int main(void)
+{ glp_graph *G;
+ int i, cnt;
+ G = glp_create_graph(sizeof(v_data), 0);
+ glp_read_graph(G, "graph.txt");
+ cnt = glp_top_sort(G, offsetof(v_data, num));
+ printf("cnt = %d\n", cnt);
+ for (i = 1; i <= G->nv; i++)
+ printf("num[%d] = %d\n", i, vertex(G->v[i])->num);
+ glp_delete_graph(G);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+\newpage
+
+\noindent
+If the file `\verb|graph.txt|' contains the following graph:
+
+\medskip
+
+\noindent\hfil
+\xymatrix @=20pt
+{
+1\ar[rrr]&&&2\ar[r]\ar[rddd]&3\ar[rd]&&&&\\
+&&&4\ar[ru]&&5\ar[r]&6\ar[rd]\ar[dd]&&\\
+7\ar[r]&8\ar[r]&9\ar[ruu]\ar[ru]\ar[r]\ar[rd]&10\ar[rr]\ar[rru]&&
+11\ar[ru]&&12\ar[r]&13\\
+&&&14\ar[r]&15\ar[rrru]\ar[rr]&&16\ar[rru]\ar[rr]&&17\\
+}
+
+\medskip\medskip
+
+\noindent
+the program output may look like follows:
+
+\begin{footnotesize}
+\begin{verbatim}
+Reading graph from `graph.txt'...
+Graph has 17 vertices and 23 arcs
+24 lines were read
+cnt = 0
+num[1] = 8
+num[2] = 9
+num[3] = 10
+num[4] = 4
+num[5] = 11
+num[6] = 12
+num[7] = 1
+num[8] = 2
+num[9] = 3
+num[10] = 5
+num[11] = 6
+num[12] = 14
+num[13] = 16
+num[14] = 7
+num[15] = 13
+num[16] = 15
+num[17] = 17
+\end{verbatim}
+\end{footnotesize}
+
+\noindent
+The output corresponds to the following vertex numbering:
+
+\medskip
+
+\noindent\hfil
+\xymatrix @=20pt
+{
+8\ar[rrr]&&&9\ar[r]\ar[rddd]&10\ar[rd]&&&&\\
+&&&4\ar[ru]&&11\ar[r]&12\ar[rd]\ar[dd]&&\\
+1\ar[r]&2\ar[r]&3\ar[ruu]\ar[ru]\ar[r]\ar[rd]&5\ar[rr]\ar[rru]&&
+6\ar[ru]&&14\ar[r]&16\\
+&&&7\ar[r]&13\ar[rrru]\ar[rr]&&15\ar[rru]\ar[rr]&&17\\
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Network optimization API routines}
+
+\section{Minimum cost flow problem}
+
+\subsection{Background}
+
+The {\it minimum cost flow problem} (MCFP) is stated as follows. Let
+there be given a directed graph (flow network) $G=(V,A)$, where $V$ is
+a set of vertices (nodes), and $A\subseteq V\times V$ is a set of arcs.
+Let for each node $i\in V$ there be given a quantity $b_i$ having the
+following meaning:
+
+if $b_i>0$, then $|b_i|$ is a {\it supply} at node $i$, which shows
+how many flow units are {\it generated} at node $i$ (or, equivalently,
+entering the network through node $i$ from outside);
+
+if $b_i<0$, then $|b_i|$ is a {\it demand} at node $i$, which shows how
+many flow units are {\it lost} at node $i$ (or, equivalently, leaving
+the network through node $i$ to outside);
+
+if $b_i=0$, then $i$ is a {\it transshipment} node, at which the flow
+is conserved, i.e. neither generated nor lost.
+
+Let also for each arc $a=(i,j)\in A$ there be given the following three
+quantities:
+
+$l_{ij}$, a (non-negative) lower bound to the flow through arc $(i,j)$;
+
+$u_{ij}$, an upper bound to the flow through arc $(i,j)$, which is the
+{\it arc capacity};
+
+$c_{ij}$, a per-unit cost of the flow through arc $(i,j)$.
+
+The problem is to find flows $x_{ij}$ through every arc of the network,
+which satisfy the specified bounds and the conservation constraints at
+all nodes, and minimize the total flow cost. Here the conservation
+constraint at a node means that the total flow entering this node
+through its incoming arcs plus the supply at this node must be equal to
+the total flow leaving this node through its outgoing arcs plus the
+demand at this node.
+
+An example of the minimum cost flow problem is shown on Fig.~1.
+
+\newpage
+
+\noindent\hfil
+\xymatrix @C=48pt
+{_{20}\ar@{~>}[d]&
+v_2\ar[r]|{_{0,10,\$2}}\ar[dd]|{_{0,9,\$3}}&
+v_3\ar[dd]|{_{2,12,\$1}}\ar[r]|{_{0,18,\$0}}&
+v_8\ar[rd]|{_{0,20,\$9}}&\\
+v_1\ar[ru]|{_{0,14,\$0}}\ar[rd]|{_{0,23,\$0}}&&&
+v_6\ar[d]|{_{0,7,\$0}}\ar[u]|{_{4,8,\$0}}&
+v_9\ar@{~>}[d]\\
+&v_4\ar[r]|{_{0,26,\$0}}&
+v_5\ar[luu]|{_{0,11,\$1}}\ar[ru]|{_{0,25,\$5}}\ar[r]|{_{0,4,\$7}}&
+v_7\ar[ru]|{_{0,15,\$3}}&_{20}\\
+}
+
+\noindent\hfil
+\begin{tabular}{ccc}
+\xymatrix @C=48pt{v_i\ar[r]|{\ l,u,\$c\ }&v_j\\}&
+\xymatrix{\hbox{\footnotesize supply}\ar@{~>}[r]&v_i\\}&
+\xymatrix{v_i\ar@{~>}[r]&\hbox{\footnotesize demand}\\}\\
+\end{tabular}
+
+\noindent\hfil
+Fig.~1. An example of the minimum cost flow problem.
+
+\medskip
+
+The minimum cost flow problem can be naturally formulated as the
+following LP problem:
+
+\noindent
+\hspace{1in}minimize
+$$z=\sum_{(i,j)\in A}c_{ij}x_{ij}\eqno(1)$$
+\hspace{1in}subject to
+$$\sum_{(i,j)\in A}x_{ij}-\sum_{(j,i)\in A}x_{ji}=b_i\ \ \ \hbox
+{for all}\ i\in V\eqno(2)$$
+$$l_{ij}\leq x_{ij}\leq u_{ij}\ \ \ \hbox{for all}\ (i,j)\in A
+\eqno(3)$$
+
+\subsection{glp\_read\_mincost --- read minimum cost flow problem data
+in DIMACS\\format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_read_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap,
+ int a_cost, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_read_mincost| reads the minimum cost flow problem
+data from a text file in DIMACS format.
+
+The parameter \verb|G| specifies the graph object, to which the problem
+data have to be stored. Note that before reading data the current
+content of the graph object is completely erased with the routine
+\verb|glp_erase_graph|.
+
+The parameter \verb|v_rhs| specifies an offset of the field of type
+\verb|double| in the vertex data block, to which the routine stores
+$b_i$, the supply/demand value. If \verb|v_rhs| $<0$, the value is not
+stored.
+
+The parameter \verb|a_low| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores
+$l_{ij}$, the lower bound to the arc flow. If \verb|a_low| $<0$, the
+lower bound is not stored.
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores
+$u_{ij}$, the upper bound to the arc flow (the arc capacity). If
+\verb|a_cap| $<0$, the upper bound is not stored.
+
+The parameter \verb|a_cost| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores
+$c_{ij}$, the per-unit cost of the arc flow. If \verb|a_cost| $<0$, the
+cost is not stored.
+
+The character string \verb|fname| specifies the name of a text file to
+be read in. (If the file name name ends with the suffix `\verb|.gz|',
+the file is assumed to be compressed, in which case the routine
+decompresses it ``on the fly''.)
+
+\returns
+
+If the operation was successful, the routine returns zero. Otherwise,
+it prints an error message and returns non-zero.
+
+\para{Example}
+
+\begin{footnotesize}
+\begin{verbatim}
+typedef struct
+{ /* vertex data block */
+ ...
+ double rhs;
+ ...
+} v_data;
+
+typedef struct
+{ /* arc data block */
+ ...
+ double low, cap, cost;
+ ...
+} a_data;
+
+int main(void)
+{ glp_graph *G;
+ int ret;
+ G = glp_create_graph(sizeof(v_data), sizeof(a_data));
+ ret = glp_read_mincost(G, offsetof(v_data, rhs),
+ offsetof(a_data, low), offsetof(a_data, cap),
+ offsetof(a_data, cost), "sample.min");
+ if (ret != 0) goto ...
+ ...
+}
+\end{verbatim}
+\end{footnotesize}
+
+\para{DIMACS minimum cost flow problem format\footnote{This
+material is based on the paper ``The First DIMACS International
+Algorithm Implementation Challenge: Problem Definitions and
+Specifications'', which is publicly available at
+\url{http://dimacs.rutgers.edu/Challenges}.}}
+\label{subsecmincost}
+
+The DIMACS input file is a plain ASCII text file. It contains
+{\it lines} of several types described below. A line is terminated with
+an end-of-line character. Fields in each line are separated by at least
+one blank space. Each line begins with a one-character designator to
+identify the line type.
+
+Note that DIMACS requires all numerical quantities to be integers in
+the range $[-2^{31},\ 2^{31}-1]$ while GLPK allows the quantities to be
+floating-point numbers.
+
+\para{Comment lines.} Comment lines give human-readable information
+about the file and are ignored by programs. Comment lines can appear
+anywhere in the file. Each comment line begins with a lower-case
+character \verb|c|.
+
+\begin{verbatim}
+ c This is a comment line
+\end{verbatim}
+
+%\newpage
+
+\para{Problem line.} There is one problem line per data file. The
+problem line must appear before any node or arc descriptor lines. It
+has the following format:
+
+\begin{verbatim}
+ p min NODES ARCS
+\end{verbatim}
+
+\newpage
+
+\noindent
+The lower-case character \verb|p| signifies that this is a problem line.
+The three-character problem designator \verb|min| identifies the file as
+containing specification information for the minimum cost flow problem.
+The \verb|NODES| field contains an integer value specifying the number
+of nodes in the network. The \verb|ARCS| field contains an integer value
+specifying the number of arcs in the network.
+
+\para{Node descriptors.} All node descriptor lines must appear before
+all arc descriptor lines. The node descriptor lines describe supply and
+demand nodes, but not transshipment nodes. That is, only nodes with
+non-zero node supply/demand values appear. There is one node descriptor
+line for each such node, with the following format:
+
+\begin{verbatim}
+ n ID FLOW
+\end{verbatim}
+
+\noindent
+The lower-case character \verb|n| signifies that this is a node
+descriptor line. The \verb|ID| field gives a node identification
+number, an integer between 1 and \verb|NODES|. The \verb|FLOW| field
+gives the amount of supply (if positive) or demand (if negative) at
+node \verb|ID|.
+
+\para{Arc descriptors.} There is one arc descriptor line for each arc
+in the network. Arc descriptor lines are of the following format:
+
+\begin{verbatim}
+ a SRC DST LOW CAP COST
+\end{verbatim}
+
+\noindent
+The lower-case character \verb|a| signifies that this is an arc
+descriptor line. For a directed arc $(i,j)$ the \verb|SRC| field gives
+the identification number $i$ for the tail endpoint, and the \verb|DST|
+field gives the identification number $j$ for the head endpoint.
+Identification numbers are integers between 1 and \verb|NODES|. The
+\verb|LOW| field specifies the minimum amount of flow that can be sent
+along arc $(i,j)$, and the \verb|CAP| field gives the maximum amount of
+flow that can be sent along arc $(i,j)$ in a feasible flow. The
+\verb|COST| field contains the per-unit cost of flow sent along arc
+$(i,j)$.
+
+\para{Example.} Below here is an example of the data file in DIMACS
+format corresponding to the minimum cost flow problem shown on Fig~1.
+
+\begin{footnotesize}
+\begin{verbatim}
+c sample.min
+c
+c This is an example of the minimum cost flow problem data
+c in DIMACS format.
+c
+p min 9 14
+c
+n 1 20
+n 9 -20
+c
+a 1 2 0 14 0
+a 1 4 0 23 0
+a 2 3 0 10 2
+a 2 4 0 9 3
+a 3 5 2 12 1
+a 3 8 0 18 0
+a 4 5 0 26 0
+a 5 2 0 11 1
+a 5 6 0 25 5
+a 5 7 0 4 7
+a 6 7 0 7 0
+a 6 8 4 8 0
+a 7 9 0 15 3
+a 8 9 0 20 9
+c
+c eof
+\end{verbatim}
+\end{footnotesize}
+
+\newpage
+
+\subsection{glp\_write\_mincost --- write minimum cost flow problem
+data in DIMACS\\format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_write_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap,
+ int a_cost, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_write_mincost| writes the minimum cost flow
+problem data to a text file in DIMACS format.
+
+The parameter \verb|G| is the graph (network) program object, which
+specifies the minimum cost flow problem instance.
+
+The parameter \verb|v_rhs| specifies an offset of the field of type
+\verb|double| in the vertex data block, which contains $b_i$, the
+supply/demand value. If \verb|v_rhs| $<0$, it is assumed that $b_i=0$
+for all nodes.
+
+The parameter \verb|a_low| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $l_{ij}$, the lower
+bound to the arc flow. If \verb|a_low| $<0$, it is assumed that
+$l_{ij}=0$ for all arcs.
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $u_{ij}$, the upper
+bound to the arc flow (the arc capacity). If the upper bound is
+specified as \verb|DBL_MAX|, it is assumed that $u_{ij}=\infty$, i.e.
+the arc is uncapacitated. If \verb|a_cap| $<0$, it is assumed that
+$u_{ij}=1$ for all arcs.
+
+The parameter \verb|a_cost| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $c_{ij}$, the
+per-unit cost of the arc flow. If \verb|a_cost| $<0$, it is assumed
+that $c_{ij}=0$ for all arcs.
+
+The character string \verb|fname| specifies a name of the text file to
+be written out. (If the file name ends with suffix `\verb|.gz|', the
+file is assumed to be compressed, in which case the routine performs
+automatic compression on writing it.)
+
+\returns
+
+If the operation was successful, the routine returns zero. Otherwise,
+it prints an error message and returns non-zero.
+
+%\newpage
+
+\subsection{glp\_mincost\_lp --- convert minimum cost flow problem
+to LP}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_mincost_lp(glp_prob *P, glp_graph *G, int names, int v_rhs,
+ int a_low, int a_cap, int a_cost);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_mincost_lp| builds LP problem (1)---(3), which
+corresponds to the specified minimum cost flow problem.
+
+The parameter \verb|P| is the resultant LP problem object to be built.
+Note that on entry its current content is erased with the routine
+\verb|glp_erase_prob|.
+
+The parameter \verb|G| is the graph (network) program object, which
+specifies the minimum cost flow problem instance.
+
+The parameter \verb|names| is a flag. If it is \verb|GLP_ON|, the
+routine uses symbolic names of the graph object components to assign
+symbolic names to the LP problem object components. If the flag is
+\verb|GLP_OFF|, no symbolic names are assigned.
+
+The parameter \verb|v_rhs| specifies an offset of the field of type
+\verb|double| in the vertex data block, which contains $b_i$, the
+supply/demand value. If \verb|v_rhs| $<0$, it is assumed that $b_i=0$
+for all nodes.
+
+The parameter \verb|a_low| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $l_{ij}$, the lower
+bound to the arc flow. If \verb|a_low| $<0$, it is assumed that
+$l_{ij}=0$ for all arcs.
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $u_{ij}$, the upper
+bound to the arc flow (the arc capacity). If the upper bound is
+specified as \verb|DBL_MAX|, it is assumed that $u_{ij}=\infty$, i.e.
+the arc is uncapacitated. If \verb|a_cap| $<0$, it is assumed that
+$u_{ij}=1$ for all arcs.
+
+The parameter \verb|a_cost| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $c_{ij}$, the
+per-unit cost of the arc flow. If \verb|a_cost| $<0$, it is assumed that
+$c_{ij}=0$ for all arcs.
+
+\para{Example}
+
+The example program below reads the minimum cost problem instance in
+DIMACS format from file `\verb|sample.min|', converts the instance to
+LP, and then writes the resultant LP in CPLEX format to file
+`\verb|mincost.lp|'.
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <glpk.h>
+
+typedef struct { double rhs; } v_data;
+typedef struct { double low, cap, cost; } a_data;
+
+int main(void)
+{ glp_graph *G;
+ glp_prob *P;
+ G = glp_create_graph(sizeof(v_data), sizeof(a_data));
+ glp_read_mincost(G, offsetof(v_data, rhs),
+ offsetof(a_data, low), offsetof(a_data, cap),
+ offsetof(a_data, cost), "sample.min");
+ P = glp_create_prob();
+ glp_mincost_lp(P, G, GLP_ON, offsetof(v_data, rhs),
+ offsetof(a_data, low), offsetof(a_data, cap),
+ offsetof(a_data, cost));
+ glp_delete_graph(G);
+ glp_write_lp(P, NULL, "mincost.lp");
+ glp_delete_prob(P);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+If `\verb|sample.min|' is the example data file from the subsection
+describing \verb|glp_read_mincost|, file `\verb|mincost.lp|' may look
+like follows:
+
+\begin{footnotesize}
+\begin{verbatim}
+Minimize
+ obj: + 3 x(2,4) + 2 x(2,3) + x(3,5) + 7 x(5,7) + 5 x(5,6)
+ + x(5,2) + 3 x(7,9) + 9 x(8,9)
+
+Subject To
+ r_1: + x(1,2) + x(1,4) = 20
+ r_2: - x(5,2) + x(2,3) + x(2,4) - x(1,2) = 0
+ r_3: + x(3,5) + x(3,8) - x(2,3) = 0
+ r_4: + x(4,5) - x(2,4) - x(1,4) = 0
+ r_5: + x(5,2) + x(5,6) + x(5,7) - x(4,5) - x(3,5) = 0
+ r_6: + x(6,7) + x(6,8) - x(5,6) = 0
+ r_7: + x(7,9) - x(6,7) - x(5,7) = 0
+ r_8: + x(8,9) - x(6,8) - x(3,8) = 0
+ r_9: - x(8,9) - x(7,9) = -20
+
+Bounds
+ 0 <= x(1,4) <= 23
+ 0 <= x(1,2) <= 14
+ 0 <= x(2,4) <= 9
+ 0 <= x(2,3) <= 10
+ 0 <= x(3,8) <= 18
+ 2 <= x(3,5) <= 12
+ 0 <= x(4,5) <= 26
+ 0 <= x(5,7) <= 4
+ 0 <= x(5,6) <= 25
+ 0 <= x(5,2) <= 11
+ 4 <= x(6,8) <= 8
+ 0 <= x(6,7) <= 7
+ 0 <= x(7,9) <= 15
+ 0 <= x(8,9) <= 20
+
+End
+\end{verbatim}
+\end{footnotesize}
+
+%\newpage
+
+\subsection{glp\_mincost\_okalg --- solve minimum cost flow problem
+with out-of-kilter\\algorithm}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_mincost_okalg(glp_graph *G, int v_rhs, int a_low, int a_cap,
+ int a_cost, double *sol, int a_x, int v_pi);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_mincost_okalg| finds optimal solution to the
+minimum cost flow problem with the out-of-kilter
+algorithm.\footnote{GLPK implementation of the out-of-kilter algorithm
+is based on the following book: L.~R.~Ford,~Jr., and D.~R.~Fulkerson,
+``Flows in Networks,'' The RAND Corp., Report R-375-PR (August 1962),
+Chap. III ``Minimal Cost Flow Problems,'' pp.~113-26.} Note that this
+routine requires all the problem data to be integer-valued.
+
+The parameter \verb|G| is a graph (network) program object which
+specifies the minimum cost flow problem instance to be solved.
+
+The parameter \verb|v_rhs| specifies an offset of the field of type
+\verb|double| in the vertex data block, which contains $b_i$, the
+supply/demand value. This value must be integer in the range
+[$-$\verb|INT_MAX|, $+$\verb|INT_MAX|]. If \verb|v_rhs| $<0$, it is
+assumed that $b_i=0$ for all nodes.
+
+The parameter \verb|a_low| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $l_{ij}$, the lower
+bound to the arc flow. This bound must be integer in the range
+[$0$, \verb|INT_MAX|]. If \verb|a_low| $<0$, it is assumed that
+$l_{ij}=0$ for all arcs.
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $u_{ij}$, the upper
+bound to the arc flow (the arc capacity). This bound must be integer in
+the range [$l_{ij}$, \verb|INT_MAX|]. If \verb|a_cap| $<0$, it is
+assumed that $u_{ij}=1$ for all arcs.
+
+\newpage
+
+The parameter \verb|a_cost| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $c_{ij}$, the
+per-unit cost of the arc flow. This value must be integer in the range
+[$-$\verb|INT_MAX|, $+$\verb|INT_MAX|]. If \verb|a_cost| $<0$, it is
+assumed that $c_{ij}=0$ for all arcs.
+
+The parameter \verb|sol| specifies a location, to which the routine
+stores the objective value (that is, the total cost) found. If
+\verb|sol| is NULL, the objective value is not stored.
+
+The parameter \verb|a_x| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores
+$x_{ij}$, the arc flow found. If \verb|a_x| $<0$, the arc flow value is
+not stored.
+
+The parameter \verb|v_pi| specifies an offset of the field of type
+\verb|double| in the vertex data block, to which the routine stores
+$\pi_i$, the node potential, which is the Lagrange multiplier for the
+corresponding flow conservation equality constraint (see (2) in
+Subsection ``Background''). If necessary, the application program may
+use the node potentials to compute $\lambda_{ij}$, reduced costs of the
+arc flows $x_{ij}$, which are the Lagrange multipliers for the arc flow
+bound constraints (see (3) ibid.), using the following formula:
+$$\lambda_{ij}=c_{ij}-(\pi_i-\pi_j),$$
+where $c_{ij}$ is the per-unit cost for arc $(i,j)$.
+
+%\newpage
+
+Note that all solution components (the objective value, arc flows, and
+node potentials) computed by the routine are always integer-valued.
+
+\returns
+
+\begin{retlist}
+0 & Optimal solution found.\\
+
+\verb|GLP_ENOPFS| & No (primal) feasible solution exists.\\
+
+\verb|GLP_EDATA| & Unable to start the search, because some problem
+data are either not integer-valued or out of range. This code is also
+returned if the total supply, which is the sum of $b_i$ over all source
+nodes (nodes with $b_i>0$), exceeds \verb|INT_MAX|.\\
+
+\verb|GLP_ERANGE| & The search was prematurely terminated because of
+integer overflow.\\
+
+\verb|GLP_EFAIL| & An error has been detected in the program logic.
+(If this code is returned for your problem instance, please report to
+\verb|<bug-glpk@gnu.org>|.)\\
+\end{retlist}
+
+\para{Comments}
+
+By design the out-of-kilter algorithm is applicable only to networks,
+where $b_i=0$ for {\it all} nodes, i.e. actually this algorithm finds a
+minimal cost {\it circulation}. Due to this requirement the routine
+\verb|glp_mincost_okalg| converts the original network to a network
+suitable for the out-of-kilter algorithm in the following
+way:\footnote{The conversion is performed internally and does not change
+the original network program object passed to the routine.}
+
+1) it adds two auxiliary nodes $s$ and $t$;
+
+2) for each original node $i$ with $b_i>0$ the routine adds auxiliary
+supply arc $(s\rightarrow i)$, flow $x_{si}$ through which is costless
+($c_{si}=0$) and fixed to $+b_i$ ($l_{si}=u_{si}=+b_i$);
+
+3) for each original node $i$ with $b_i<0$ the routine adds auxiliary
+demand arc $(i\rightarrow t)$, flow $x_{it}$ through which is costless
+($c_{it}=0$) and fixed to $-b_i$ ($l_{it}=u_{it}=-b_i$);
+
+4) finally, the routine adds auxiliary feedback arc $(t\rightarrow s)$,
+flow $x_{ts}$ through which is also costless ($c_{ts}=0$) and fixed to
+$F$ ($l_{ts}=u_{ts}=F$), where $\displaystyle F=\sum_{b_i>0}b_i$ is the
+total supply.
+
+\newpage
+
+\para{Example}
+
+The example program below reads the minimum cost problem instance in
+DIMACS format from file `\verb|sample.min|', solves it by using the
+routine \verb|glp_mincost_okalg|, and writes the solution found on the
+standard output.
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+typedef struct { double rhs, pi; } v_data;
+typedef struct { double low, cap, cost, x; } a_data;
+
+#define node(v) ((v_data *)((v)->data))
+#define arc(a) ((a_data *)((a)->data))
+
+int main(void)
+{ glp_graph *G;
+ glp_vertex *v, *w;
+ glp_arc *a;
+ int i, ret;
+ double sol;
+ G = glp_create_graph(sizeof(v_data), sizeof(a_data));
+ glp_read_mincost(G, offsetof(v_data, rhs),
+ offsetof(a_data, low), offsetof(a_data, cap),
+ offsetof(a_data, cost), "sample.min");
+ ret = glp_mincost_okalg(G, offsetof(v_data, rhs),
+ offsetof(a_data, low), offsetof(a_data, cap),
+ offsetof(a_data, cost), &sol, offsetof(a_data, x),
+ offsetof(v_data, pi));
+ printf("ret = %d; sol = %5g\n", ret, sol);
+ for (i = 1; i <= G->nv; i++)
+ { v = G->v[i];
+ printf("node %d: pi = %5g\n", i, node(v)->pi);
+ for (a = v->out; a != NULL; a = a->t_next)
+ { w = a->head;
+ printf("arc %d->%d: x = %5g; lambda = %5g\n",
+ v->i, w->i, arc(a)->x,
+ arc(a)->cost - (node(v)->pi - node(w)->pi));
+ }
+ }
+ glp_delete_graph(G);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+If `\verb|sample.min|' is the example data file from the subsection
+describing \verb|glp_read_mincost|, the output may look like follows:
+
+\begin{footnotesize}
+\begin{verbatim}
+Reading min-cost flow problem data from `sample.min'...
+Flow network has 9 nodes and 14 arcs
+24 lines were read
+ret = 0; sol = 213
+node 1: pi = -12
+arc 1->4: x = 13; lambda = 0
+arc 1->2: x = 7; lambda = 0
+node 2: pi = -12
+arc 2->4: x = 0; lambda = 3
+arc 2->3: x = 7; lambda = 0
+node 3: pi = -14
+arc 3->8: x = 5; lambda = 0
+arc 3->5: x = 2; lambda = 3
+node 4: pi = -12
+arc 4->5: x = 13; lambda = 0
+node 5: pi = -12
+arc 5->7: x = 4; lambda = -1
+arc 5->6: x = 11; lambda = 0
+arc 5->2: x = 0; lambda = 1
+node 6: pi = -17
+arc 6->8: x = 4; lambda = 3
+arc 6->7: x = 7; lambda = -3
+node 7: pi = -20
+arc 7->9: x = 11; lambda = 0
+node 8: pi = -14
+arc 8->9: x = 9; lambda = 0
+node 9: pi = -23
+\end{verbatim}
+\end{footnotesize}
+
+\subsection{glp\_mincost\_relax4 --- solve minimum cost flow problem
+with relaxation\\method of Bertsekas and Tseng (RELAX-IV)}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_mincost_relax4(glp_graph *G, int v_rhs, int a_low, int a_cap,
+ int a_cost, int crash, double *sol, int a_x, int a_rc);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_mincost_relax4| finds optimal solution to the
+minimum cost flow problem with the relaxation method RELAX-IV developed
+by Bertsekas and Tseng.\footnote{GLPK implementation of this method is
+based on a C translation of the original Fortran code {\tt RELAX4}
+written by Dimitri P. Bertsekas and Paul Tseng, with a contribution by
+Jonathan Eckstein in the phase II initialization.} This method is one
+of most efficient methods for network optimization.
+
+Note that this routine requires all the problem data to be
+integer-valued.
+
+The parameter \verb|G| is a graph (network) program object which
+specifies the minimum cost flow problem instance to be solved.
+
+The parameter \verb|v_rhs| specifies an offset of the field of type
+\verb|double| in the vertex data block, which contains $b_i$, the
+supply/demand value. This value must be integer in the range
+[$-$\verb|INT_MAX|/4, $+$\verb|INT_MAX|/4]. If \verb|v_rhs| $<0$, it is
+assumed that $b_i=0$ for all nodes.
+
+The parameter \verb|a_low| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $l_{ij}$, the lower
+bound to the arc flow. This bound must be integer in the range
+{\linebreak} [$0$, \verb|INT_MAX|/4]. If \verb|a_low| $<0$, it is
+assumed that $l_{ij}=0$ for all arcs.
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $u_{ij}$, the upper
+bound to the arc flow (the arc capacity). This bound must be integer in
+the range [$l_{ij}$, \verb|INT_MAX|/4]. If \verb|a_cap| $<0$, it is
+assumed that $u_{ij}=1$ for all arcs.
+
+The parameter \verb|a_cost| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $c_{ij}$, the
+per-unit cost of the arc flow. This value must be integer in the range
+[$-$\verb|INT_MAX|/4, $+$\verb|INT_MAX|/4]. If \verb|a_cost| $<0$, it
+is assumed that $c_{ij}=0$ for all arcs.
+
+\newpage
+
+The parameter \verb|crash| is an option that specifies initialization
+method:
+
+0 --- default initialization is used;
+
+1 --- auction initialization is used.
+
+\noindent
+If \verb|crash| = 1, initialization is performed with a special crash
+procedure based on an auction/shorest path method. This option is
+recommended for difficult problems where the default initialization
+results in long running times.
+
+The parameter \verb|sol| specifies a location, to which the routine
+stores the objective value (that is, the total cost) found. If
+\verb|sol| is NULL, the objective value is not stored.
+
+The parameter \verb|a_x| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores
+$x_{ij}$, the arc flow found. If \verb|a_x| $<0$, the arc flow value is
+not stored.
+
+The parameter \verb|a_rc| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores
+the reduced cost for corresponding arc flow (see (3) in Subsection
+``Background''). If \verb|a_rc| $<0$, the reduced cost is not stored.
+
+Note that all solution components (the objective value, arc flows, and
+node potentials) computed by the routine are always integer-valued.
+
+\returns
+
+\begin{retlist}
+0 & Optimal solution found.\\
+
+\verb|GLP_ENOPFS| & No (primal) feasible solution exists.\\
+
+\verb|GLP_EDATA| & Unable to start the search, because some problem
+data are either not integer-valued or out of range.\\
+
+\verb|GLP_ERANGE| & Unable to start the search because of integer
+overflow.\\
+\end{retlist}
+
+\para{Example}
+
+The example program below reads the minimum cost problem instance in
+DIMACS format from file `\verb|sample.min|', solves it by using the
+routine \verb|glp_mincost_relax4|, and writes the solution found on the
+standard output.
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+typedef struct { double rhs; } v_data;
+typedef struct { double low, cap, cost, x, rc; } a_data;
+
+#define node(v) ((v_data *)((v)->data))
+#define arc(a) ((a_data *)((a)->data))
+
+int main(void)
+{ glp_graph *G;
+ glp_vertex *v, *w;
+ glp_arc *a;
+ int i, ret;
+ double sol;
+ G = glp_create_graph(sizeof(v_data), sizeof(a_data));
+ glp_read_mincost(G, offsetof(v_data, rhs),
+ offsetof(a_data, low), offsetof(a_data, cap),
+ offsetof(a_data, cost), "sample.min");
+ ret = glp_mincost_relax4(G, offsetof(v_data, rhs),
+ offsetof(a_data, low), offsetof(a_data, cap),
+ offsetof(a_data, cost), 0, &sol, offsetof(a_data, x),
+ offsetof(a_data, rc));
+ printf("ret = %d; sol = %5g\n", ret, sol);
+ for (i = 1; i <= G->nv; i++)
+ { v = G->v[i];
+ for (a = v->out; a != NULL; a = a->t_next)
+ { w = a->head;
+ printf("arc %d->%d: x = %5g; rc = %5g\n",
+ v->i, w->i, arc(a)->x, arc(a)->rc);
+ }
+ }
+ glp_delete_graph(G);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+If `\verb|sample.min|' is the example data file from the subsection
+describing \verb|glp_read_mincost|, the output may look like follows:
+
+\begin{footnotesize}
+\begin{verbatim}
+Reading min-cost flow problem data from `sample.min'...
+Flow network has 9 nodes and 14 arcs
+24 lines were read
+ret = 0; sol = 213
+arc 1->4: x = 13; rc = 0
+arc 1->2: x = 7; rc = 0
+arc 2->4: x = 0; rc = 3
+arc 2->3: x = 7; rc = 0
+arc 3->8: x = 5; rc = 0
+arc 3->5: x = 2; rc = 3
+arc 4->5: x = 13; rc = 0
+arc 5->7: x = 4; rc = -1
+arc 5->6: x = 11; rc = 0
+arc 5->2: x = 0; rc = 1
+arc 6->8: x = 4; rc = 3
+arc 6->7: x = 7; rc = -3
+arc 7->9: x = 11; rc = 0
+arc 8->9: x = 9; rc = 0
+\end{verbatim}
+\end{footnotesize}
+
+\subsection{glp\_netgen --- Klingman's network problem generator}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_netgen(glp_graph *G, int v_rhs, int a_cap, int a_cost,
+ const int parm[1+15]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_netgen| is a GLPK version of the network problem
+generator developed by Dr.~Darwin~Klingman.\footnote{D.~Klingman,
+A.~Napier, and J.~Stutz. NETGEN: A program for generating large scale
+capacitated assignment, transportation, and minimum cost flow networks.
+Management Science 20 (1974), 814-20.} It can create capacitated and
+uncapacitated minimum cost flow (or transshipment), transportation, and
+assignment problems.
+
+The parameter \verb|G| specifies the graph object, to which the
+generated problem data have to be stored. Note that on entry the graph
+object is erased with the routine \verb|glp_erase_graph|.
+
+\newpage
+
+The parameter \verb|v_rhs| specifies an offset of the field of type
+\verb|double| in the vertex data block, to which the routine stores the
+supply or demand value. If \verb|v_rhs| $<0$, the value is not stored.
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores the
+arc capacity. If \verb|a_cap| $<0$, the capacity is not stored.
+
+The parameter \verb|a_cost| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores the
+per-unit cost if the arc flow. If \verb|a_cost| $<0$, the cost is not
+stored.
+
+The array \verb|parm| contains description of the network to be
+generated:
+
+\begin{tabular}{@{}lll@{}}
+\verb|parm[0] |& &not used\\
+\verb|parm[1] |&\verb|iseed |&8-digit positive random number seed\\
+\verb|parm[2] |&\verb|nprob |&8-digit problem id number\\
+\verb|parm[3] |&\verb|nodes |&total number of nodes\\
+\verb|parm[4] |&\verb|nsorc |&total number of source nodes
+(including transshipment nodes)\\
+\verb|parm[5] |&\verb|nsink |&total number of sink nodes
+(including transshipment nodes)\\
+\verb|parm[6] |&\verb|iarcs |&number of arc\\
+\verb|parm[7] |&\verb|mincst|&minimum cost for arcs\\
+\verb|parm[8] |&\verb|maxcst|&maximum cost for arcs\\
+\verb|parm[9] |&\verb|itsup |&total supply\\
+\verb|parm[10]|&\verb|ntsorc|&number of transshipment source nodes\\
+\verb|parm[11]|&\verb|ntsink|&number of transshipment sink nodes\\
+\verb|parm[12]|&\verb|iphic |&percentage of skeleton arcs to be given
+the maximum cost\\
+\verb|parm[13]|&\verb|ipcap |&percentage of arcs to be capacitated\\
+\verb|parm[14]|&\verb|mincap|&minimum upper bound for capacitated arcs\\
+\verb|parm[15]|&\verb|maxcap|&maximum upper bound for capacitated arcs\\
+\end{tabular}
+
+\returns
+
+If the instance was successfully generated, the routine
+\verb|glp_netgen| returns zero; otherwise, if specified parameters are
+inconsistent, the routine returns a non-zero error code.
+
+\para{Notes}
+
+1. The routine generates a transportation problem if:
+$${\tt nsorc}+{\tt nsink}={\tt nodes},
+\ {\tt ntsorc}=0,\ \mbox{and}\ {\tt ntsink}=0.$$
+
+2. The routine generates an assignment problem if the requirements for
+a transportation problem are met and:
+$${\tt nsorc}={\tt nsink}\ \mbox{and}\ {\tt itsup}={\tt nsorc}.$$
+
+3. The routine always generates connected graphs. So, if the number of
+requested arcs has been reached and the generated instance is not fully
+connected, the routine generates a few remaining arcs to ensure
+connectedness. Thus, the actual number of arcs generated by the routine
+may be greater than the requested number of arcs.
+
+\newpage
+
+\subsection{glp\_netgen\_prob --- Klingman's standard network problem
+instance}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_netgen_prob(int nprob, int parm[1+15]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_netgen_prob| provides the set of parameters for
+Klingman's network problem generator (see the routine
+\verb|glp_netgen|), which describe a standard network problem instance.
+
+The parameter \verb|nprob| ($101\leq$ \verb|nprob| $\leq 150$)
+specifies the problem instance number.
+
+The array \verb|parm| contains description of the network, provided by
+the routine. (For detailed description of these parameters see comments
+to the routine \verb|glp_netgen|.)
+
+\para{Problem characteristics}
+
+The table below shows characteristics of Klingman's standard network
+problem instances.
+$$
+\begin{array}{crrr}
+{\rm Problem} & {\rm Nodes} & {\rm Arcs} & {\rm Optimum} \\
+\hline
+101 & 5000 & 25336 & 6191726 \\
+102 & 5000 & 25387 & 72337144 \\
+103 & 5000 & 25355 & 218947553 \\
+104 & 5000 & 25344 & -19100371 \\
+105 & 5000 & 25332 & 31192578 \\
+106 & 5000 & 12870 & 4314276 \\
+107 & 5000 & 37832 & 7393769 \\
+108 & 5000 & 50309 & 8405738 \\
+109 & 5000 & 75299 & 9190300 \\
+110 & 5000 & 12825 & 8975048 \\
+111 & 5000 & 37828 & 4747532 \\
+112 & 5000 & 50325 & 4012671 \\
+113 & 5000 & 75318 & 2979725 \\
+114 & 5000 & 26514 & 5821181 \\
+115 & 5000 & 25962 & 6353310 \\
+116 & 5000 & 25304 & 5915426 \\
+117 & 5000 & 12816 & 4420560 \\
+118 & 5000 & 37797 & 7045842 \\
+119 & 5000 & 50301 & 7724179 \\
+120 & 5000 & 75330 & 8455200 \\
+121 & 5000 & 25000 & 66366360 \\
+122 & 5000 & 25000 & 30997529 \\
+123 & 5000 & 25000 & 23388777 \\
+124 & 5000 & 25000 & 17803443 \\
+125 & 5000 & 25000 & 14119622 \\
+\end{array}
+\hspace{.5in}
+\begin{array}{crrr}
+{\rm Problem} & {\rm Nodes} & {\rm Arcs} & {\rm Optimum} \\
+\hline
+126 & 5000 & 12500 & 18802218 \\
+127 & 5000 & 37500 & 27674647 \\
+128 & 5000 & 50000 & 30906194 \\
+129 & 5000 & 75000 & 40905209 \\
+130 & 5000 & 12500 & 38939608 \\
+131 & 5000 & 37500 & 16752978 \\
+132 & 5000 & 50000 & 13302951 \\
+133 & 5000 & 75000 & 9830268 \\
+134 & 1000 & 25000 & 3804874 \\
+135 & 2500 & 25000 & 11729616 \\
+136 & 7500 & 25000 & 33318101 \\
+137 & 10000 & 25000 & 46426030 \\
+138 & 5000 & 25000 & 60710879 \\
+139 & 5000 & 25000 & 32729682 \\
+140 & 5000 & 25000 & 27183831 \\
+141 & 5000 & 25000 & 19963286 \\
+142 & 5000 & 25000 & 20243457 \\
+143 & 5000 & 25000 & 18586777 \\
+144 & 5000 & 25000 & 2504591 \\
+145 & 5000 & 25000 & 215956138 \\
+146 & 5000 & 25000 & 2253113811 \\
+147 & 5000 & 25000 & -427908373 \\
+148 & 5000 & 25000 & -92965318 \\
+149 & 5000 & 25000 & 86051224 \\
+150 & 5000 & 25000 & 619314919 \\
+\end{array}
+$$
+
+\newpage
+
+\subsection{glp\_gridgen --- grid-like network problem generator}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_gridgen(glp_graph *G, int v_rhs, int a_cap, int a_cost,
+ const int parm[1+14]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_gridgen| is a GLPK version of the grid-like
+network problem generator developed by Yusin Lee and Jim
+Orlin.\footnote{Y.~Lee and J.~Orlin. GRIDGEN generator., 1991. The
+original code is publicly available from
+\url{ftp://dimacs.rutgers.edu/pub/netflow/generators/network/gridgen}.}
+
+The parameter \verb|G| specifies the graph object, to which the
+generated problem data have to be stored. Note that on entry the graph
+object is erased with the routine \verb|glp_erase_graph|.
+
+The parameter \verb|v_rhs| specifies an offset of the field of type
+\verb|double| in the vertex data block, to which the routine stores the
+supply or demand value. If \verb|v_rhs| $<0$, the value is not stored.
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores the
+arc capacity. If \verb|a_cap| $<0$, the capacity is not stored.
+
+The parameter \verb|a_cost| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores the
+per-unit cost if the arc flow. If \verb|a_cost| $<0$, the cost is not
+stored.
+
+The array \verb|parm| contains parameters of the network to be
+generated:
+
+\begin{tabular}{@{}ll@{}}
+\verb|parm[0] |&not used\\
+\verb|parm[1] |&two-ways arcs indicator:\\
+ &1 --- if links in both direction should be generated\\
+ &0 --- otherwise\\
+\verb|parm[2] |&random number seed (a positive integer)\\
+\verb|parm[3] |&number of nodes (the number of nodes generated might
+be slightly different to\\&make the network a grid)\\
+\verb|parm[4] |&grid width\\
+\verb|parm[5] |&number of sources\\
+\verb|parm[6] |&number of sinks\\
+\verb|parm[7] |&average degree\\
+\verb|parm[8] |&total flow\\
+\verb|parm[9] |&distribution of arc costs:
+1 --- uniform, 2 --- exponential\\
+\verb|parm[10]|&lower bound for arc cost (uniform),
+$100\lambda$ (exponential)\\
+\verb|parm[11]|&upper bound for arc cost (uniform),
+not used (exponential)\\
+\verb|parm[12]|&distribution of arc capacities:
+1 --- uniform, 2 --- exponential\\
+\verb|parm[13]|&lower bound for arc capacity (uniform),
+$100\lambda$ (exponential)\\
+\verb|parm[14]|&upper bound for arc capacity (uniform),
+not used (exponential)\\
+\end{tabular}
+
+\returns
+
+If the instance was successfully generated, the routine
+\verb|glp_gridgen| returns zero; otherwise, if specified parameters are
+inconsistent, the routine returns a non-zero error code.
+
+\newpage
+
+\para{Comments\footnote{This material is based on comments
+to the original version of GRIDGEN.}}
+
+This network generator generates a grid-like network plus a super node.
+In additional to the arcs connecting the nodes in the grid, there is an
+arc from each supply node to the super node and from the super node to
+each demand node to guarantee feasiblity. These arcs have very high
+costs and very big capacities.
+
+The idea of this network generator is as follows: First, a grid of
+$n_1\times n_2$ is generated. For example, $5\times 3$. The nodes are
+numbered as 1 to 15, and the supernode is numbered as
+$n_1\times n_2+1$. Then arcs between adjacent nodes are generated.
+For these arcs, the user is allowed to specify either to generate
+two-way arcs or one-way arcs. If two-way arcs are to be generated, two
+arcs, one in each direction, will be generated between each adjacent
+node pairs. Otherwise, only one arc will be generated. If this is the
+case, the arcs will be generated in alterntive directions as shown
+below.
+
+\medskip
+
+\noindent\hfil
+\xymatrix
+{1\ar[r]\ar[d]&2\ar[r]&3\ar[r]\ar[d]&4\ar[r]&5\ar[d]\\
+6\ar[d]&7\ar[l]\ar[u]&8\ar[l]\ar[d]&9\ar[l]\ar[u]&10\ar[l]\ar[d]\\
+11\ar[r]&12\ar[r]\ar[u]&13\ar[r]&14\ar[r]\ar[u]&15\\
+}
+
+\medskip
+
+Then the arcs between the super node and the source/sink nodes are
+added as mentioned before. If the number of arcs still doesn't reach
+the requirement, additional arcs will be added by uniformly picking
+random node pairs. There is no checking to prevent multiple arcs
+between any pair of nodes. However, there will be no self-arcs (arcs
+that poins back to its tail node) in the network.
+
+The source and sink nodes are selected uniformly in the network, and
+the imbalances of each source/sink node are also assigned by uniform
+distribution.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Maximum flow problem}
+
+\subsection{Background}
+
+The {\it maximum flow problem} (MAXFLOW) is stated as follows. Let
+there be given a directed graph (flow network) $G=(V,A)$, where $V$ is
+a set of vertices (nodes), and $A\subseteq V\times V$ is a set of arcs.
+Let also for each arc $a=(i,j)\in A$ there be given its capacity
+$u_{ij}$. The problem is, for given {\it source} node $s\in V$ and
+{\it sink} node $t\in V$, to find flows $x_{ij}$ through every arc of
+the network, which satisfy the specified arc capacities and the
+conservation constraints at all nodes, and maximize the total flow $F$
+through the network from $s$ to $t$. Here the conservation constraint
+at a node means that the total flow entering this node through its
+incoming arcs (plus $F$, if it is the source node) must be equal to the
+total flow leaving this node through its outgoing arcs (plus $F$, if it
+is the sink node). An example of the maximum flow problem,
+where $s=v_1$ and $t=v_9$, is shown on Fig.~2.
+
+\medskip
+
+\noindent\hfil
+\xymatrix @C=48pt
+{_{F}\ar@{~>}[d]&
+v_2\ar[r]|{_{10}}\ar[dd]|{_{9}}&
+v_3\ar[dd]|{_{12}}\ar[r]|{_{18}}&
+v_8\ar[rd]|{_{20}}&\\
+v_1\ar[ru]|{_{14}}\ar[rd]|{_{23}}&&&
+v_6\ar[d]|{_{7}}\ar[u]|{_{8}}&
+v_9\ar@{~>}[d]\\
+&v_4\ar[r]|{_{26}}&
+v_5\ar[luu]|{_{11}}\ar[ru]|{_{25}}\ar[r]|{_{4}}&
+v_7\ar[ru]|{_{15}}&_{F}\\
+}
+
+\medskip
+
+\noindent\hfil
+Fig.~2. An example of the maximum flow problem.
+
+\medskip
+
+The maximum flow problem can be naturally formulated as the following
+LP problem:
+
+\noindent
+\hspace{1in}maximize
+$$F\eqno(4)$$
+\hspace{1in}subject to
+$$\sum_{(i,j)\in A}x_{ij}-\sum_{(j,i)\in A}x_{ji}=\left\{
+\begin{array}{@{\ }rl}
++F,&\hbox{for}\ i=s\\
+ 0,&\hbox{for all}\ i\in V\backslash\{s,t\}\\
+-F,&\hbox{for}\ i=t\\
+\end{array}
+\right.\eqno(5)
+$$
+$$0\leq x_{ij}\leq u_{ij}\ \ \ \hbox{for all}\ (i,j)\in A
+\eqno(6)$$
+
+\noindent
+where $F\geq 0$ is an additional variable playing the role of the
+objective.
+
+Another LP formulation of the maximum flow problem, which does not
+include the variable $F$, is the following:
+
+\noindent
+\hspace{1in}maximize
+$$z=\sum_{(s,j)\in A}x_{sj}-\sum_{(j,s)\in A}x_{js}\ (=F)\eqno(7)$$
+\hspace{1in}subject to
+$$\sum_{(i,j)\in A}x_{ij}-\sum_{(j,i)\in A}x_{ji}\left\{
+\begin{array}{@{\ }rl}
+\geq 0,&\hbox{for}\ i=s\\
+=0,&\hbox{for all}\ i\in V\backslash\{s,t\}\\
+\leq 0,&\hbox{for}\ i=t\\
+\end{array}
+\right.\eqno(8)
+$$
+$$0\leq x_{ij}\leq u_{ij}\ \ \ \hbox{for all}\ (i,j)\in A
+\eqno(9)$$
+
+\newpage
+
+\subsection{glp\_read\_maxflow --- read maximum flow problem data in
+DIMACS\\format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_read_maxflow(glp_graph *G, int *s, int *t, int a_cap,
+ const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_read_maxflow| reads the maximum flow problem
+data from a text file in DIMACS format.
+
+The parameter \verb|G| specifies the graph object, to which the problem
+data have to be stored. Note that before reading data the current
+content of the graph object is completely erased with the routine
+\verb|glp_erase_graph|.
+
+The pointer \verb|s| specifies a location, to which the routine stores
+the ordinal number of the source node. If \verb|s| is \verb|NULL|, the
+source node number is not stored.
+
+The pointer \verb|t| specifies a location, to which the routine stores
+the ordinal number of the sink node. If \verb|t| is \verb|NULL|, the
+sink node number is not stored.
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores
+$u_{ij}$, the arc capacity. If \verb|a_cap| $<0$, the arc capacity is
+not stored.
+
+The character string \verb|fname| specifies the name of a text file to
+be read in. (If the file name name ends with the suffix `\verb|.gz|',
+the file is assumed to be compressed, in which case the routine
+decompresses it ``on the fly''.)
+
+\returns
+
+If the operation was successful, the routine returns zero. Otherwise,
+it prints an error message and returns non-zero.
+
+\para{Example}
+
+\begin{footnotesize}
+\begin{verbatim}
+typedef struct
+{ /* arc data block */
+ ...
+ double cap;
+ ...
+} a_data;
+
+int main(void)
+{ glp_graph *G;
+ int s, t, ret;
+ G = glp_create_graph(..., sizeof(a_data));
+ ret = glp_read_maxflow(G, &s, &t, offsetof(a_data, cap),
+ "sample.max");
+ if (ret != 0) goto ...
+ ...
+}
+\end{verbatim}
+\end{footnotesize}
+
+\newpage
+
+\para{DIMACS maximum flow problem format\footnote{This material is
+based on the paper ``The First DIMACS International Algorithm
+Implementation Challenge: Problem Definitions and Specifications'',
+which is publicly available at
+\url{http://dimacs.rutgers.edu/Challenges/}.}}
+\label{subsecmaxflow}
+
+The DIMACS input file is a plain ASCII text file. It contains
+{\it lines} of several types described below. A line is terminated with
+an end-of-line character. Fields in each line are separated by at least
+one blank space. Each line begins with a one-character designator to
+identify the line type.
+
+Note that DIMACS requires all numerical quantities to be integers in
+the range $[-2^{31},\ 2^{31}-1]$ while GLPK allows the quantities to be
+floating-point numbers.
+
+\para{Comment lines.} Comment lines give human-readable information
+about the file and are ignored by programs. Comment lines can appear
+anywhere in the file. Each comment line begins with a lower-case
+character \verb|c|.
+
+\begin{verbatim}
+ c This is a comment line
+\end{verbatim}
+
+\para{Problem line.} There is one problem line per data file. The
+problem line must appear before any node or arc descriptor lines.
+It has the following format:
+
+\begin{verbatim}
+ p max NODES ARCS
+\end{verbatim}
+
+\noindent
+The lower-case character \verb|p| signifies that this is a problem line.
+The three-character problem designator \verb|max| identifies the file as
+containing specification information for the maximum flow problem. The
+\verb|NODES| field contains an integer value specifying the number of
+nodes in the network. The \verb|ARCS| field contains an integer value
+specifying the number of arcs in the network.
+
+\para{Node descriptors.} Two node descriptor lines for the source and
+sink nodes must appear before all arc descriptor lines. They may appear
+in either order, each with the following format:
+
+\begin{verbatim}
+ n ID WHICH
+\end{verbatim}
+
+\noindent
+The lower-case character \verb|n| signifies that this a node descriptor
+line. The \verb|ID| field gives a node identification number,
+an integer between 1 and \verb|NODES|. The \verb|WHICH| field gives
+either a lower-case \verb|s| or \verb|t|, designating the source and
+sink, respectively.
+
+\para{Arc descriptors.} There is one arc descriptor line for each arc
+in the network. Arc descriptor lines are of the following format:
+
+\begin{verbatim}
+ a SRC DST CAP
+\end{verbatim}
+
+\noindent
+The lower-case character \verb|a| signifies that this is an arc
+descriptor line. For a directed arc $(i,j)$ the \verb|SRC| field gives
+the identification number $i$ for the tail endpoint, and the \verb|DST|
+field gives the identification number $j$ for the head endpoint.
+Identification numbers are integers between 1 and \verb|NODES|. The
+\verb|CAP| field gives the arc capacity, i.e. maximum amount of flow
+that can be sent along arc $(i,j)$ in a feasible flow.
+
+\para{Example.} Below here is an example of the data file in DIMACS
+format corresponding to the maximum flow problem shown on Fig~2.
+
+\begin{footnotesize}
+\begin{verbatim}
+c sample.max
+c
+c This is an example of the maximum flow problem data
+c in DIMACS format.
+c
+p max 9 14
+c
+n 1 s
+n 9 t
+c
+a 1 2 14
+a 1 4 23
+a 2 3 10
+a 2 4 9
+a 3 5 12
+a 3 8 18
+a 4 5 26
+a 5 2 11
+a 5 6 25
+a 5 7 4
+a 6 7 7
+a 6 8 8
+a 7 9 15
+a 8 9 20
+c
+c eof
+\end{verbatim}
+\end{footnotesize}
+
+\subsection{glp\_write\_maxflow --- write maximum flow problem data in
+DIMACS\\format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_write_maxflow(glp_graph *G, int s, int t, int a_cap,
+ const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_write_maxflow| writes the maximum flow problem
+data to a text file in DIMACS format.
+
+The parameter \verb|G| is the graph (network) program object, which
+specifies the maximum flow problem instance.
+
+The parameter \verb|s| specifies the ordinal number of the source node.
+
+The parameter \verb|t| specifies the ordinal number of the sink node.
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $u_{ij}$, the upper
+bound to the arc flow (the arc capacity). If the upper bound is
+specified as \verb|DBL_MAX|, it is assumed that $u_{ij}=\infty$, i.e.
+the arc is uncapacitated. If \verb|a_cap| $<0$, it is assumed that
+$u_{ij}=1$ for all arcs.
+
+The character string \verb|fname| specifies a name of the text file to
+be written out. (If the file name ends with suffix `\verb|.gz|', the
+file is assumed to be compressed, in which case the routine performs
+automatic compression on writing it.)
+
+\returns
+
+If the operation was successful, the routine returns zero. Otherwise,
+it prints an error message and returns non-zero.
+
+\newpage
+
+\subsection{glp\_maxflow\_lp --- convert maximum flow problem to LP}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_maxflow_lp(glp_prob *P, glp_graph *G, int names, int s, int t,
+ int a_cap);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_maxflow_lp| builds LP problem (7)---(9), which
+corresponds to the specified maximum flow problem.
+
+The parameter \verb|P| is the resultant LP problem object to be built.
+Note that on entry its current content is erased with the routine
+\verb|glp_erase_prob|.
+
+The parameter \verb|G| is the graph (network) program object, which
+specifies the maximum flow problem instance.
+
+The parameter \verb|names| is a flag. If it is \verb|GLP_ON|, the
+routine uses symbolic names of the graph object components to assign
+symbolic names to the LP problem object components. If the flag is
+\verb|GLP_OFF|, no symbolic names are assigned.
+
+The parameter \verb|s| specifies the ordinal number of the source node.
+
+The parameter \verb|t| specifies the ordinal number of the sink node.
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $u_{ij}$, the upper
+bound to the arc flow (the arc capacity). If the upper bound is
+specified as \verb|DBL_MAX|, it is assumed that $u_{ij}=\infty$, i.e.
+the arc is uncapacitated. If \verb|a_cap| $<0$, it is assumed that
+$u_{ij}=1$ for all arcs.
+
+\para{Example}
+
+The example program below reads the maximum flow problem in DIMACS
+format from file `\verb|sample.max|', converts the instance to LP, and
+then writes the resultant LP in CPLEX format to file
+`\verb|maxflow.lp|'.
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <glpk.h>
+
+int main(void)
+{ glp_graph *G;
+ glp_prob *P;
+ int s, t;
+ G = glp_create_graph(0, sizeof(double));
+ glp_read_maxflow(G, &s, &t, 0, "sample.max");
+ P = glp_create_prob();
+ glp_maxflow_lp(P, G, GLP_ON, s, t, 0);
+ glp_delete_graph(G);
+ glp_write_lp(P, NULL, "maxflow.lp");
+ glp_delete_prob(P);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+If `\verb|sample.max|' is the example data file from the previous
+subsection, the output `\verb|maxflow.lp|' may look like follows:
+
+\newpage
+
+\begin{footnotesize}
+\begin{verbatim}
+Maximize
+ obj: + x(1,4) + x(1,2)
+
+Subject To
+ r_1: + x(1,2) + x(1,4) >= 0
+ r_2: - x(5,2) + x(2,3) + x(2,4) - x(1,2) = 0
+ r_3: + x(3,5) + x(3,8) - x(2,3) = 0
+ r_4: + x(4,5) - x(2,4) - x(1,4) = 0
+ r_5: + x(5,2) + x(5,6) + x(5,7) - x(4,5) - x(3,5) = 0
+ r_6: + x(6,7) + x(6,8) - x(5,6) = 0
+ r_7: + x(7,9) - x(6,7) - x(5,7) = 0
+ r_8: + x(8,9) - x(6,8) - x(3,8) = 0
+ r_9: - x(8,9) - x(7,9) <= 0
+
+Bounds
+ 0 <= x(1,4) <= 23
+ 0 <= x(1,2) <= 14
+ 0 <= x(2,4) <= 9
+ 0 <= x(2,3) <= 10
+ 0 <= x(3,8) <= 18
+ 0 <= x(3,5) <= 12
+ 0 <= x(4,5) <= 26
+ 0 <= x(5,7) <= 4
+ 0 <= x(5,6) <= 25
+ 0 <= x(5,2) <= 11
+ 0 <= x(6,8) <= 8
+ 0 <= x(6,7) <= 7
+ 0 <= x(7,9) <= 15
+ 0 <= x(8,9) <= 20
+
+End
+\end{verbatim}
+\end{footnotesize}
+
+\subsection{glp\_maxflow\_ffalg --- solve maximum flow problem with
+Ford-Fulkerson\\algorithm}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_maxflow_ffalg(glp_graph *G, int s, int t, int a_cap, double *sol,
+ int a_x, int v_cut);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_mincost_ffalg| finds optimal solution to the
+maximum flow problem with the Ford-Fulkerson algorithm.\footnote{GLPK
+implementation of the Ford-Fulkerson algorithm is based on the
+following book: L.~R.~Ford,~Jr., and D.~R.~Fulkerson, ``Flows in
+Networks,'' The RAND Corp., Report R-375-PR (August 1962), Chap. I
+``Static Maximal Flow,'' pp.~30-33.} Note that this routine requires
+all the problem data to be integer-valued.
+
+The parameter \verb|G| is a graph (network) program object which
+specifies the maximum flow problem instance to be solved.
+
+The parameter $s$ specifies the ordinal number of the source node.
+
+The parameter $t$ specifies the ordinal number of the sink node.
+
+\newpage
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $u_{ij}$, the upper
+bound to the arc flow (the arc capacity). This bound must be integer in
+the range [0, \verb|INT_MAX|]. If \verb|a_cap| $<0$, it is assumed that
+$u_{ij}=1$ for all arcs.
+
+The parameter \verb|sol| specifies a location, to which the routine
+stores the objective value (that is, the total flow from $s$ to $t$)
+found. If \verb|sol| is NULL, the objective value is not stored.
+
+The parameter \verb|a_x| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores
+$x_{ij}$, the arc flow found. If \verb|a_x| $<0$, the arc flow values
+are not stored.
+
+The parameter \verb|v_cut| specifies an offset of the field of type
+\verb|int| in the vertex data block, to which the routine stores node
+flags corresponding to the optimal solution found: if the node flag is
+1, the node is labelled, and if the node flag is 0, the node is
+unlabelled. The calling program may use these node flags to determine
+the {\it minimal cut}, which is a subset of arcs whose one endpoint is
+labelled and other is not. If \verb|v_cut| $<0$, the node flags are not
+stored.
+
+Note that all solution components (the objective value and arc flows)
+computed by the routine are always integer-valued.
+
+\returns
+
+\begin{retlist}
+0 & Optimal solution found.\\
+
+\verb|GLP_EDATA| & Unable to start the search, because some problem
+data are either not integer-valued or out of range.\\
+\end{retlist}
+
+\para{Example}
+
+The example program shown below reads the maximum flow problem instance
+in DIMACS format from file `\verb|sample.max|', solves it using the
+routine \verb|glp_maxflow_ffalg|, and write the solution found to the
+standard output.
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+typedef struct { int cut; } v_data;
+typedef struct { double cap, x; } a_data;
+
+#define node(v) ((v_data *)((v)->data))
+#define arc(a) ((a_data *)((a)->data))
+
+int main(void)
+{ glp_graph *G;
+ glp_vertex *v, *w;
+ glp_arc *a;
+ int i, s, t, ret;
+ double sol;
+ G = glp_create_graph(sizeof(v_data), sizeof(a_data));
+ glp_read_maxflow(G, &s, &t, offsetof(a_data, cap),
+ "sample.max");
+ ret = glp_maxflow_ffalg(G, s, t, offsetof(a_data, cap),
+ &sol, offsetof(a_data, x), offsetof(v_data, cut));
+ printf("ret = %d; sol = %5g\n", ret, sol);
+ for (i = 1; i <= G->nv; i++)
+ { v = G->v[i];
+ for (a = v->out; a != NULL; a = a->t_next)
+ { w = a->head;
+ printf("x[%d->%d] = %5g (%d)\n", v->i, w->i,
+ arc(a)->x, node(v)->cut ^ node(w)->cut);
+ }
+ }
+ glp_delete_graph(G);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+If `\verb|sample.max|' is the example data file from the subsection
+describing \verb|glp_read_maxflow|, the output may look like follows:
+
+\begin{footnotesize}
+\begin{verbatim}
+Reading maximum flow problem data from `sample.max'...
+Flow network has 9 nodes and 14 arcs
+24 lines were read
+ret = 0; sol = 29
+x[1->4] = 19 (0)
+x[1->2] = 10 (0)
+x[2->4] = 0 (0)
+x[2->3] = 10 (1)
+x[3->8] = 10 (0)
+x[3->5] = 0 (1)
+x[4->5] = 19 (0)
+x[5->7] = 4 (1)
+x[5->6] = 15 (0)
+x[5->2] = 0 (0)
+x[6->8] = 8 (1)
+x[6->7] = 7 (1)
+x[7->9] = 11 (0)
+x[8->9] = 18 (0)
+\end{verbatim}
+\end{footnotesize}
+
+\subsection{glp\_rmfgen --- Goldfarb's maximum flow problem generator}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_rmfgen(glp_graph *G, int *s, int *t, int a_cap, const int parm[1+5]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_rmfgen| is a GLPK version of the maximum flow
+problem generator developed by D.~Goldfarb and
+M.~Grigoriadis.\footnote{D.~Goldfarb and M.~D.~Grigoriadis,
+``A computational comparison of the Dinic and network simplex methods
+for maximum flow.'' Annals of Op. Res. 13 (1988),
+pp.~83-123.}$^{,}$\footnote{U.~Derigs and W.~Meier, ``Implementing
+Goldberg's max-flow algorithm: A computational investigation.''
+Zeitschrift f\"ur Operations Research 33 (1989),
+pp.~383-403.}$^{,}$\footnote{The original code of RMFGEN implemented by
+Tamas Badics is publicly available from
+\url{ftp://dimacs.rutgers.edu/pub/netflow/generators/network/genrmf}.}
+
+The parameter \verb|G| specifies the graph object, to which the
+generated problem data have to be stored. Note that on entry the graph
+object is erased with the routine \verb|glp_erase_graph|.
+
+The pointers \verb|s| and \verb|t| specify locations, to which the
+routine stores the source and sink node numbers, respectively. If
+\verb|s| or \verb|t| is \verb|NULL|, corresponding node number is not
+stored.
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores the
+arc capacity. If \verb|a_cap| $<0$, the capacity is not stored.
+
+\newpage
+
+The array \verb|parm| contains description of the network to be
+generated:
+
+\begin{tabular}{@{}lll@{}}
+\verb|parm[0]|& &not used\\
+\verb|parm[1]|&\verb|seed|&random number seed (a positive integer)\\
+\verb|parm[2]|&\verb|a |&frame size\\
+\verb|parm[3]|&\verb|b |&depth\\
+\verb|parm[4]|&\verb|c1 |&minimal arc capacity\\
+\verb|parm[5]|&\verb|c2 |&maximal arc capacity\\
+\end{tabular}
+
+\returns
+
+If the instance was successfully generated, the routine
+\verb|glp_netgen| returns zero; otherwise, if specified parameters are
+inconsistent, the routine returns a non-zero error code.
+
+\para{Comments\footnote{This material is based on comments to the
+original version of RMFGEN.}}
+
+The generated network is as follows. It has $b$ pieces of frames of
+size $a\times a$. (So alltogether the number of vertices is
+$a\times a\times b$.)
+
+In each frame all the vertices are connected with their neighbours
+(forth and back). In addition the vertices of a frame are connected
+one to one with the vertices of next frame using a random permutation
+of those vertices.
+
+The source is the lower left vertex of the first frame, the sink is
+the upper right vertex of the $b$-th frame.
+
+\begin{verbatim}
+ t
+ +-------+
+ | .|
+ | . |
+ / | / |
+ +-------+/ -+ b
+ | | |/.
+ a | -v- |/
+ | | |/
+ +-------+ 1
+ s a
+\end{verbatim}
+
+The capacities are randomly chosen integers from the range of
+$[c_1,c_2]$ in the case of interconnecting edges, and $c_2\cdot a^2$
+for the in-frame edges.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Assignment problem}
+
+\subsection{Background}
+
+Let there be given an undirected bipartite graph $G=(R\cup S,E)$, where
+$R$ and $S$ are disjoint sets of vertices (nodes), and
+$E\subseteq R\times S$ is a set of edges. Let also for each edge
+$e=(i,j)\in E$ there be given its cost $c_{ij}$. A {\it matching}
+(which in case of bipartite graph is also called {\it assignment})
+$M\subseteq E$ in $G$ is a set of pairwise non-adjacent edges, that is,
+no two edges in $M$ share a common vertex. A matching, which matches
+all vertices of the graph, is called a {\it perfect matching}.
+Obviously, a perfect matching in bipartite graph $G=(R\cup S,E)$
+defines some bijection $R\leftrightarrow S$.
+
+The {\it assignment problem} has two different variants. In the first
+variant the problem is to find matching (assignment) $M$, which
+maximizes the sum:
+$$\sum_{(i,j)\in M}c_{ij}\eqno(10)$$
+(so this variant is also called the {\it maximum weighted bipartite
+matching problem} or, if all $c_{ij}=1$, the {\it maximum cardinality
+bipartite matching problem}). In the second, classic variant the
+problem is to find {\it perfect} matching (assignment) $M$, which
+minimizes or maximizes the sum (10).
+
+An example of the assignment problem, which is the maximum weighted
+bipartite matching problem, is shown on Fig. 3.
+
+The maximum weighted bipartite matching problem can be naturally
+formulated as the following LP problem:
+
+\noindent
+\hspace{1in}maximize
+$$z=\sum_{(i,j)\in E}c_{ij}x_{ij}\eqno(11)$$
+\hspace{1in}subject to
+$$\sum_{(i,j)\in E}x_{ij}\leq 1\ \ \ \hbox{for all}\ i\in R\eqno(12)$$
+$$\sum_{(i,j)\in E}x_{ij}\leq 1\ \ \ \hbox{for all}\ j\in S\eqno(13)$$
+$$\ \ \ \ \ \ \ \ 0\leq x_{ij}\leq 1\ \ \ \hbox{for all}\ (i,j)\in E
+\eqno(14)$$
+
+\noindent
+where $x_{ij}=1$ means that $(i,j)\in M$, and $x_{ij}=0$ means that
+$(i,j)\notin M$.\footnote{The constraint matrix of LP formulation
+(11)---(14) is totally unimodular, due to which $x_{ij}\in\{0,1\}$ for
+any basic solution.}
+
+\newpage
+
+\noindent\hfil
+\xymatrix @C=48pt
+{v_1\ar@{-}[rr]|{_{13}}\ar@{-}[rrd]|{_{21}}\ar@{-}[rrddd]|(.2){_{20}}&&
+v_9\\
+v_2\ar@{-}[rr]|{_{12}}\ar@{-}[rrdd]|(.3){_{8}}
+\ar@{-}[rrddd]|(.4){_{26}}&&v_{10}\\
+v_3\ar@{-}[rr]|(.2){_{22}}\ar@{-}[rrdd]|(.3){_{11}}&&v_{11}\\
+v_4\ar@{-}[rruuu]|(.6){_{12}}\ar@{-}[rr]|(.2){_{36}}
+\ar@{-}[rrdd]|(.7){_{25}}&&v_{12}\\
+v_5\ar@{-}[rruu]|(.42){_{41}}\ar@{-}[rru]|(.4){_{40}}
+\ar@{-}[rr]|(.75){_{11}}\ar@{-}[rrd]|(.6){_{4}}\ar@{-}[rrdd]|{_{8}}
+\ar@{-}[rrddd]|{_{35}}\ar@{-}[rrdddd]|{_{32}}&&v_{13}\\
+v_6\ar@{-}[rruuuuu]|(.7){_{13}}&&v_{14}\\
+v_7\ar@{-}[rruuuuu]|(.15){_{19}}&&v_{15}\\
+v_8\ar@{-}[rruuuuuu]|(.25){_{39}}\ar@{-}[rruuuuu]|(.65){_{15}}&&
+v_{16}\\
+&&v_{17}\\
+}
+
+\medskip
+
+\noindent\hfil
+Fig.~3. An example of the assignment problem.
+
+\medskip
+
+Similarly, the perfect assignment problem can be naturally formulated
+as the following LP problem:
+
+\noindent
+\hspace{1in}minimize (or maximize)
+$$z=\sum_{(i,j)\in E}c_{ij}x_{ij}\eqno(15)$$
+\hspace{1in}subject to
+$$\sum_{(i,j)\in E}x_{ij}=1\ \ \ \hbox{for all}\ i\in R\eqno(16)$$
+$$\sum_{(i,j)\in E}x_{ij}=1\ \ \ \hbox{for all}\ j\in S\eqno(17)$$
+$$\ \ \ \ \ \ \ \ 0\leq x_{ij}\leq 1\ \ \ \hbox{for all}\ (i,j)\in E
+\eqno(18)$$
+
+\noindent
+where variables $x_{ij}$ have the same meaning as for (11)---(14)
+above.
+
+In GLPK an undirected bipartite graph $G=(R\cup S,E)$ is represented as
+directed graph $\overline{G}=(V,A)$, where $V=R\cup S$ and
+$A=\{(i,j):(i,j)\in E\}$, i.e. every edge $(i,j)\in E$ in $G$
+corresponds to arc $(i\rightarrow j)\in A$ in $\overline{G}$.
+
+\newpage
+
+\setlength{\parskip}{4.4pt}
+
+\subsection{glp\_read\_asnprob --- read assignment problem data in
+DIMACS format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_read_asnprob(glp_graph *G, int v_set, int a_cost, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_read_asnprob| reads the assignment problem data
+from a text file in DIMACS format.
+
+The parameter \verb|G| specifies the graph object, to which the problem
+data have to be stored. Note that before reading data the current
+content of the graph object is completely erased with the routine
+\verb|glp_erase_graph|.
+
+The parameter \verb|v_set| specifies an offset of the field of type
+\verb|int| in the vertex data block, to which the routine stores the
+node set indicator:
+
+0 --- the node is in set $R$;
+
+1 --- the node is in set $S$.
+
+\noindent
+If \verb|v_set| $<0$, the node set indicator is not stored.
+
+The parameter \verb|a_cost| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores the
+edge cost $c_{ij}$. If \verb|a_cost| $<0$, the edge cost is not stored.
+
+The character string \verb|fname| specifies the name of a text file to
+be read in. (If the file name name ends with the suffix `\verb|.gz|',
+the file is assumed to be compressed, in which case the routine
+decompresses it ``on the fly''.)
+
+\returns
+
+If the operation was successful, the routine returns zero. Otherwise,
+it prints an error message and returns non-zero.
+
+\para{Example.} Below here is an example program that read the
+assignment problem data in DIMACS format from a text file
+`\verb|sample.asn|'.
+
+\begin{footnotesize}
+\begin{verbatim}
+typedef struct
+{ /* vertex data block */
+ ...
+ int set;
+ ...
+} v_data;
+
+typedef struct
+{ /* arc data block */
+ ...
+ double cost;
+ ...
+} a_data;
+
+int main(void)
+{ glp_graph *G;
+ int ret;
+ G = glp_create_graph(sizeof(v_data), sizeof(a_data));
+ ret = glp_read_asnprob(G, offsetof(v_data, set),
+ offsetof(a_data, cost), "sample.asn");
+ if (ret != 0) goto ...
+ ...
+}
+\end{verbatim}
+\end{footnotesize}
+
+\setlength{\parskip}{5pt}
+
+\newpage
+
+\para{DIMACS assignment problem format\footnote{This material is based
+on the paper ``The First DIMACS International Algorithm Implementation
+Challenge: Problem Definitions and Specifications'', which is
+publicly available at \url{http://dimacs.rutgers.edu/Challenges/}.}}
+\label{subsecasnprob}
+
+The DIMACS input file is a plain ASCII text file. It contains
+{\it lines} of several types described below. A line is terminated with
+an end-of-line character. Fields in each line are separated by at least
+one blank space. Each line begins with a one-character designator to
+identify the line type.
+
+Note that DIMACS requires all numerical quantities to be integers in
+the range $[-2^{31},\ 2^{31}-1]$ while GLPK allows the quantities to be
+floating-point numbers.
+
+\para{Comment lines.} Comment lines give human-readable information
+about the file and are ignored by programs. Comment lines can appear
+anywhere in the file. Each comment line begins with a lower-case
+character \verb|c|.
+
+\begin{verbatim}
+ c This is a comment line
+\end{verbatim}
+
+\para{Problem line.} There is one problem line per data file. The
+problem line must appear before any node or arc descriptor lines. It
+has the following format:
+
+\begin{verbatim}
+ p asn NODES EDGES
+\end{verbatim}
+
+\noindent
+The lower-case character \verb|p| signifies that this is a problem line.
+The three-character problem designator \verb|asn| identifies the file as
+containing specification information for the assignment problem.
+The \verb|NODES| field contains an integer value specifying the total
+number of nodes in the graph (i.e. in both sets $R$ and $S$). The
+\verb|EDGES| field contains an integer value specifying the number of
+edges in the graph.
+
+\para{Node descriptors.} All node descriptor lines must appear before
+all edge descriptor lines. The node descriptor lines lists the nodes in
+set $R$ only, and all other nodes are assumed to be in set $S$. There
+is one node descriptor line for each such node, with the following
+format:
+
+\begin{verbatim}
+ n ID
+\end{verbatim}
+
+\noindent
+The lower-case character \verb|n| signifies that this is a node
+descriptor line. The \verb|ID| field gives a node identification number,
+an integer between 1 and \verb|NODES|.
+
+\para{Edge descriptors.} There is one edge descriptor line for each
+edge in the graph. Edge descriptor lines are of the following format:
+
+\begin{verbatim}
+ a SRC DST COST
+\end{verbatim}
+
+\noindent
+The lower-case character \verb|a| signifies that this is an edge
+descriptor line. For each edge $(i,j)$, where $i\in R$ and $j\in S$,
+the \verb|SRC| field gives the identification number of vertex $i$, and
+the \verb|DST| field gives the identification number of vertex $j$.
+Identification numbers are integers between 1 and \verb|NODES|. The
+\verb|COST| field contains the cost of edge $(i,j)$.
+
+\para{Example.} Below here is an example of the data file in DIMACS
+format corresponding to the assignment problem shown on Fig~3.
+
+\begin{footnotesize}
+\begin{verbatim}
+c sample.asn
+c
+c This is an example of the assignment problem data
+c in DIMACS format.
+c
+p asn 17 22
+c
+n 1
+n 2
+n 3
+n 4
+n 5
+n 6
+n 7
+n 8
+c
+a 1 9 13
+a 1 10 21
+a 1 12 20
+a 2 10 12
+a 2 12 8
+a 2 13 26
+a 3 11 22
+a 3 13 11
+a 4 9 12
+a 4 12 36
+a 4 14 25
+a 5 11 41
+a 5 12 40
+a 5 13 11
+a 5 14 4
+a 5 15 8
+a 5 16 35
+a 5 17 32
+a 6 9 13
+a 7 10 19
+a 8 10 39
+a 8 11 15
+c
+c eof
+\end{verbatim}
+\end{footnotesize}
+
+\subsection{glp\_write\_asnprob --- write assignment problem data in
+DIMACS format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_write_asnprob(glp_graph *G, int v_set, int a_cost, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_write_asnprob| writes the assignment problem data
+to a text file in DIMACS format.
+
+The parameter \verb|G| is the graph program object, which specifies the
+assignment problem instance.
+
+The parameter \verb|v_set| specifies an offset of the field of type
+\verb|int| in the vertex data block, which contains the node set
+indicator:
+
+0 --- the node is in set $R$;
+
+1 --- the node is in set $S$.
+
+\noindent
+If \verb|v_set| $<0$, it is assumed that a node having no incoming arcs
+is in set $R$, and a node having no outgoing arcs is in set $S$.
+
+The parameter \verb|a_cost| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $c_{ij}$, the edge
+cost. If \verb|a_cost| $<0$, it is assumed that $c_{ij}=1$ for all
+edges.
+
+\newpage
+
+The character string \verb|fname| specifies a name of the text file to
+be written out. (If the file name ends with suffix `\verb|.gz|', the
+file is assumed to be compressed, in which case the routine performs
+automatic compression on writing it.)
+
+\para{Note}
+
+The routine \verb|glp_write_asnprob| does not check that the specified
+graph object correctly represents a bipartite graph. To make sure that
+the problem data are correct, use the routine \verb|glp_check_asnprob|.
+
+\returns
+
+If the operation was successful, the routine returns zero. Otherwise,
+it prints an error message and returns non-zero.
+
+\vspace*{-4pt}
+
+\subsection{glp\_check\_asnprob --- check correctness of assignment
+problem data}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_check_asnprob(glp_graph *G, int v_set);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_check_asnprob| checks that the specified graph
+object \verb|G| correctly represents a bipartite graph.
+
+The parameter \verb|v_set| specifies an offset of the field of type
+\verb|int| in the vertex data block, which contains the node set
+indicator:
+
+0 --- the node is in set $R$;
+
+1 --- the node is in set $S$.
+
+\noindent
+If \verb|v_set| $<0$, it is assumed that a node having no incoming arcs
+is in set $R$, and a node having no outgoing arcs is in set $S$.
+
+\returns
+
+0 --- the data are correct;
+
+1 --- the set indicator of some node is 0, however, that node has one
+or more incoming arcs;
+
+2 --- the set indicator of some node is 1, however, that node has one
+or more outgoing arcs;
+
+3 --- the set indicator of some node is invalid (neither 0 nor 1);
+
+4 --- some node has both incoming and outgoing arcs.
+
+\subsection{glp\_asnprob\_lp --- convert assignment problem to LP}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_asnprob_lp(glp_prob *P, int form, glp_graph *G, int names, int v_set,
+ int a_cost);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_asnprob_lp| builds LP problem, which corresponds
+to the specified assignment problem.
+
+\newpage
+
+The parameter \verb|P| is the resultant LP problem object to be built.
+Note that on entry its current content is erased with the routine
+\verb|glp_erase_prob|.
+
+The parameter \verb|form| defines which LP formulation should be used:
+
+\verb|GLP_ASN_MIN| --- perfect matching (15)---(18), minimization;
+
+\verb|GLP_ASN_MAX| --- perfect matching (15)---(18), maximization;
+
+\verb|GLP_ASN_MMP| --- maximum weighted matching (11)---(14).
+
+The parameter \verb|G| is the graph program object, which specifies the
+assignment problem instance.
+
+The parameter \verb|names| is a flag. If it is \verb|GLP_ON|, the
+routine uses symbolic names of the graph object components to assign
+symbolic names to the LP problem object components. If the \verb|flag|
+is \verb|GLP_OFF|, no symbolic names are assigned.
+
+The parameter \verb|v_set| specifies an offset of the field of type
+\verb|int| in the vertex data block, which contains the node set
+indicator:
+
+0 --- the node is in set $R$;
+
+1 --- the node is in set $S$.
+
+\noindent
+If \verb|v_set| $<0$, it is assumed that a node having no incoming arcs
+is in set $R$, and a node having no outgoing arcs is in set $S$.
+
+The parameter \verb|a_cost| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $c_{ij}$, the edge
+cost. If \verb|a_cost| $<0$, it is assumed that $c_{ij}=1$ for all
+edges.
+
+\returns
+
+If the LP problem has been successfully built, the routine
+\verb|glp_asnprob_lp| returns zero, otherwise, non-zero (see the
+routine \verb|glp_check_asnprob|).
+
+\para{Example}
+
+The example program below reads the assignment problem instance in
+DIMACS format from file `\verb|sample.asn|', converts the instance to
+LP (11)---(14), and writes the resultant LP in CPLEX format to file
+`\verb|matching.lp|'.
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <glpk.h>
+
+typedef struct { int set; } v_data;
+typedef struct { double cost; } a_data;
+
+int main(void)
+{ glp_graph *G;
+ glp_prob *P;
+ G = glp_create_graph(sizeof(v_data), sizeof(a_data));
+ glp_read_asnprob(G, offsetof(v_data, set),
+ offsetof(a_data, cost), "sample.asn");
+ P = glp_create_prob();
+ glp_asnprob_lp(P, GLP_ASN_MMP, G, GLP_ON,
+ offsetof(v_data, set), offsetof(a_data, cost));
+ glp_delete_graph(G);
+ glp_write_lp(P, NULL, "matching.lp");
+ glp_delete_prob(P);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+\newpage
+
+If `\verb|sample.asn|' is the example data file from the subsection
+describing \verb|glp_read_asnprob|, file `\verb|matching.lp|' may look
+like follows:
+
+\begin{footnotesize}
+\begin{verbatim}
+Maximize
+ obj: + 20 x(1,12) + 21 x(1,10) + 13 x(1,9) + 26 x(2,13) + 8 x(2,12)
+ + 12 x(2,10) + 11 x(3,13) + 22 x(3,11) + 25 x(4,14) + 36 x(4,12)
+ + 12 x(4,9) + 32 x(5,17) + 35 x(5,16) + 8 x(5,15) + 4 x(5,14)
+ + 11 x(5,13) + 40 x(5,12) + 41 x(5,11) + 13 x(6,9) + 19 x(7,10)
+ + 15 x(8,11) + 39 x(8,10)
+
+Subject To
+ r_1: + x(1,9) + x(1,10) + x(1,12) <= 1
+ r_2: + x(2,10) + x(2,12) + x(2,13) <= 1
+ r_3: + x(3,11) + x(3,13) <= 1
+ r_4: + x(4,9) + x(4,12) + x(4,14) <= 1
+ r_5: + x(5,11) + x(5,12) + x(5,13) + x(5,14) + x(5,15) + x(5,16)
+ + x(5,17) <= 1
+ r_6: + x(6,9) <= 1
+ r_7: + x(7,10) <= 1
+ r_8: + x(8,10) + x(8,11) <= 1
+ r_9: + x(6,9) + x(4,9) + x(1,9) <= 1
+ r_10: + x(8,10) + x(7,10) + x(2,10) + x(1,10) <= 1
+ r_11: + x(8,11) + x(5,11) + x(3,11) <= 1
+ r_12: + x(5,12) + x(4,12) + x(2,12) + x(1,12) <= 1
+ r_13: + x(5,13) + x(3,13) + x(2,13) <= 1
+ r_14: + x(5,14) + x(4,14) <= 1
+ r_15: + x(5,15) <= 1
+ r_16: + x(5,16) <= 1
+ r_17: + x(5,17) <= 1
+
+Bounds
+ 0 <= x(1,12) <= 1
+ 0 <= x(1,10) <= 1
+ 0 <= x(1,9) <= 1
+ 0 <= x(2,13) <= 1
+ 0 <= x(2,12) <= 1
+ 0 <= x(2,10) <= 1
+ 0 <= x(3,13) <= 1
+ 0 <= x(3,11) <= 1
+ 0 <= x(4,14) <= 1
+ 0 <= x(4,12) <= 1
+ 0 <= x(4,9) <= 1
+ 0 <= x(5,17) <= 1
+ 0 <= x(5,16) <= 1
+ 0 <= x(5,15) <= 1
+ 0 <= x(5,14) <= 1
+ 0 <= x(5,13) <= 1
+ 0 <= x(5,12) <= 1
+ 0 <= x(5,11) <= 1
+ 0 <= x(6,9) <= 1
+ 0 <= x(7,10) <= 1
+ 0 <= x(8,11) <= 1
+ 0 <= x(8,10) <= 1
+
+End
+\end{verbatim}
+\end{footnotesize}
+
+\newpage
+
+\subsection{glp\_asnprob\_okalg --- solve assignment problem with
+out-of-kilter\\algorithm}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_asnprob_okalg(int form, glp_graph *G, int v_set, int a_cost,
+ double *sol, int a_x);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_mincost_okalg| finds optimal solution to the
+assignment problem with the out-of-kilter
+algorithm.\footnote{GLPK implementation of the out-of-kilter algorithm
+is based on the following book: L.~R.~Ford,~Jr., and D.~R.~Fulkerson,
+``Flows in Networks,'' The RAND Corp., Report R-375-PR (August 1962),
+Chap. III ``Minimal Cost Flow Problems,'' pp.~113-26.} Note that this
+routine requires all the problem data to be integer-valued.
+
+The parameter \verb|form| defines which LP formulation should be used:
+
+\verb|GLP_ASN_MIN| --- perfect matching (15)---(18), minimization;
+
+\verb|GLP_ASN_MAX| --- perfect matching (15)---(18), maximization;
+
+\verb|GLP_ASN_MMP| --- maximum weighted matching (11)---(14).
+
+The parameter \verb|G| is the graph program object, which specifies the
+assignment problem instance.
+
+The parameter \verb|v_set| specifies an offset of the field of type
+\verb|int| in the vertex data block, which contains the node set
+indicator:
+
+0 --- the node is in set $R$;
+
+1 --- the node is in set $S$.
+
+\noindent
+If \verb|v_set| $<0$, it is assumed that a node having no incoming arcs
+is in set $R$, and a node having no outgoing arcs is in set $S$.
+
+The parameter \verb|a_cost| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $c_{ij}$, the edge
+cost. This value must be integer in the range [\verb|-INT_MAX|,
+\verb|+INT_MAX|]. If \verb|a_cost| $<0$, it is assumed that $c_{ij}=1$
+for all edges.
+
+The parameter \verb|sol| specifies a location, to which the routine
+stores the objective value (that is, the total cost) found.
+If \verb|sol| is \verb|NULL|, the objective value is not stored.
+
+The parameter \verb|a_x| specifies an offset of the field of type
+\verb|int| in the arc data block, to which the routine stores $x_{ij}$.
+If \verb|a_x| $<0$, this value is not stored.
+
+\returns
+
+\begin{retlist}
+0 & Optimal solution found.\\
+
+\verb|GLP_ENOPFS| & No (primal) feasible solution exists.\\
+
+\verb|GLP_EDATA| & Unable to start the search, because the assignment
+problem data are either incorrect (this error is detected by the
+routine \verb|glp_check_asnprob|), not integer-valued or out of range.\\
+
+\verb|GLP_ERANGE| & The search was prematurely terminated because of
+integer overflow.\\
+
+\verb|GLP_EFAIL| & An error has been detected in the program logic.
+(If this code is returned for your problem instance, please report to
+\verb|<bug-glpk@gnu.org>|.)\\
+\end{retlist}
+
+\newpage
+
+\para{Comments}
+
+Since the out-of-kilter algorithm is designed to find a minimal cost
+circulation, the routine \verb|glp_asnprob_okalg| converts the original
+graph to a network suitable for this algorithm in the following
+way:\footnote{The conversion is performed internally and does not
+change the original graph program object passed to the routine.}
+
+1) it replaces each edge $(i,j)$ by arc $(i\rightarrow j)$,
+flow $x_{ij}$ through which has zero lower bound ($l_{ij}=0$), unity
+upper bound ($u_{ij}=1$), and per-unit cost $+c_{ij}$ (in case of
+\verb|GLP_ASN_MIN|), or $-c_{ij}$ (in case of \verb|GLP_ASN_MAX| and
+\verb|GLP_ASN_MMP|);
+
+2) then it adds one auxiliary feedback node $k$;
+
+3) for each original node $i\in R$ the routine adds auxiliary supply
+arc $(k\rightarrow i)$, flow $x_{ki}$ through which is costless
+($c_{ki}=0$) and either fixed at 1 ($l_{ki}=u_{ki}=1$, in case of
+\verb|GLP_ASN_MIN| and \verb|GLP_ASN_MAX|) or has zero lower bound and
+unity upper bound ($l_{ij}=0$, $u_{ij}=1$, in case of
+\verb|GLP_ASN_MMP|);
+
+4) similarly, for each original node $j\in S$ the routine adds
+auxiliary demand arc $(j\rightarrow k)$, flow $x_{jk}$ through which is
+costless ($c_{jk}=0$) and either fixed at 1 ($l_{jk}=u_{jk}=1$, in case
+of \verb|GLP_ASN_MIN| and \verb|GLP_ASN_MAX|) or has zero lower bound
+and unity upper bound ($l_{jk}=0$, $u_{jk}=1$, in case of
+\verb|GLP_ASN_MMP|).
+
+\para{Example}
+
+The example program shown below reads the assignment problem instance
+in DIMACS format from file `\verb|sample.asn|', solves it by using the
+routine \verb|glp_asnprob_okalg|, and writes the solution found to the
+standard output.
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+typedef struct { int set; } v_data;
+typedef struct { double cost; int x; } e_data;
+
+#define node(v) ((v_data *)((v)->data))
+#define edge(e) ((e_data *)((e)->data))
+
+int main(void)
+{ glp_graph *G;
+ glp_vertex *v;
+ glp_arc *e;
+ int i, ret;
+ double sol;
+ G = glp_create_graph(sizeof(v_data), sizeof(e_data));
+ glp_read_asnprob(G, offsetof(v_data, set),
+ offsetof(e_data, cost), "sample.asn");
+ ret = glp_asnprob_okalg(GLP_ASN_MMP, G,
+ offsetof(v_data, set), offsetof(e_data, cost), &sol,
+ offsetof(e_data, x));
+ printf("ret = %d; sol = %5g\n", ret, sol);
+ for (i = 1; i <= G->nv; i++)
+ { v = G->v[i];
+ for (e = v->out; e != NULL; e = e->t_next)
+ printf("edge %2d %2d: x = %d; c = %g\n",
+ e->tail->i, e->head->i, edge(e)->x, edge(e)->cost);
+ }
+ glp_delete_graph(G);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+If `\verb|sample.asn|' is the example data file from the subsection
+describing \verb|glp_read_asnprob|, the output may look like follows:
+
+\begin{footnotesize}
+\begin{verbatim}
+Reading assignment problem data from `sample.asn'...
+Assignment problem has 8 + 9 = 17 nodes and 22 arcs
+38 lines were read
+ret = 0; sol = 180
+edge 1 12: x = 1; c = 20
+edge 1 10: x = 0; c = 21
+edge 1 9: x = 0; c = 13
+edge 2 13: x = 1; c = 26
+edge 2 12: x = 0; c = 8
+edge 2 10: x = 0; c = 12
+edge 3 13: x = 0; c = 11
+edge 3 11: x = 1; c = 22
+edge 4 14: x = 1; c = 25
+edge 4 12: x = 0; c = 36
+edge 4 9: x = 0; c = 12
+edge 5 17: x = 0; c = 32
+edge 5 16: x = 1; c = 35
+edge 5 15: x = 0; c = 8
+edge 5 14: x = 0; c = 4
+edge 5 13: x = 0; c = 11
+edge 5 12: x = 0; c = 40
+edge 5 11: x = 0; c = 41
+edge 6 9: x = 1; c = 13
+edge 7 10: x = 0; c = 19
+edge 8 11: x = 0; c = 15
+edge 8 10: x = 1; c = 39
+\end{verbatim}
+\end{footnotesize}
+
+\subsection{glp\_asnprob\_hall --- find bipartite matching of maximum
+cardinality}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_asnprob_hall(glp_graph *G, int v_set, int a_x);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_asnprob_hall| finds a matching of maximal
+cardinality in the specified bipartite graph. It uses a version of the
+Fortran routine \verb|MC21A| developed by
+I.~S.~Duff\footnote{I.~S.~Duff, Algorithm 575: Permutations for
+zero-free diagonal, ACM Trans. on Math. Softw. 7 (1981),\linebreak
+pp.~387-390.}, which implements Hall's algorithm.\footnote{M.~Hall,
+``An Algorithm for Distinct Representatives,'' Am. Math. Monthly 63
+(1956), pp.~716-717.}
+
+The parameter \verb|G| is a pointer to the graph program object.
+
+The parameter \verb|v_set| specifies an offset of the field of type
+\verb|int| in the vertex data block, which contains the node set
+indicator:
+
+0 --- the node is in set $R$;
+
+1 --- the node is in set $S$.
+
+\newpage
+
+\noindent
+If \verb|v_set| $<0$, it is assumed that a node having no incoming arcs
+is in set $R$, and a node having no outgoing arcs is in set $S$.
+
+The parameter \verb|a_x| specifies an offset of the field of type
+\verb|int| in the arc data block, to which the routine stores $x_{ij}$.
+If \verb|a_x| $<0$, this value is not stored.
+
+\returns
+
+The routine \verb|glp_asnprob_hall| returns the cardinality of the
+matching found. However, if the specified graph is incorrect (as
+detected by the routine \verb|glp_check_asnprob|), this routine returns
+a negative value.
+
+\para{Comments}
+
+The same solution may be obtained with the routine
+\verb|glp_asnprob_okalg| (for LP formulation \verb|GLP_ASN_MMP| and
+all edge costs equal to 1). However, the routine
+\verb|glp_asnprob_hall| is much faster.
+
+\para{Example}
+
+The example program shown below reads the assignment problem instance
+in DIMACS format from file `\verb|sample.asn|', finds a bipartite
+matching of maximal cardinality by using the routine
+\verb|glp_asnprob_hall|, and writes the solution found to the standard
+output.
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+typedef struct { int set; } v_data;
+typedef struct { int x; } e_data;
+
+#define node(v) ((v_data *)((v)->data))
+#define edge(e) ((e_data *)((e)->data))
+
+int main(void)
+{ glp_graph *G;
+ glp_vertex *v;
+ glp_arc *e;
+ int i, card;
+ G = glp_create_graph(sizeof(v_data), sizeof(e_data));
+ glp_read_asnprob(G, offsetof(v_data, set), -1,
+ "sample.asn");
+ card = glp_asnprob_hall(G, offsetof(v_data, set),
+ offsetof(e_data, x));
+ printf("card = %d\n", card);
+ for (i = 1; i <= G->nv; i++)
+ { v = G->v[i];
+ for (e = v->out; e != NULL; e = e->t_next)
+ printf("edge %2d %2d: x = %d\n",
+ e->tail->i, e->head->i, edge(e)->x);
+ }
+ glp_delete_graph(G);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+If `\verb|sample.asn|' is the example data file from the subsection
+describing \verb|glp_read_asnprob|, the output may look like follows:
+
+\newpage
+
+\begin{footnotesize}
+\begin{verbatim}
+Reading assignment problem data from `sample.asn'...
+Assignment problem has 8 + 9 = 17 nodes and 22 arcs
+38 lines were read
+card = 7
+edge 1 12: x = 1
+edge 1 10: x = 0
+edge 1 9: x = 0
+edge 2 13: x = 1
+edge 2 12: x = 0
+edge 2 10: x = 0
+edge 3 13: x = 0
+edge 3 11: x = 1
+edge 4 14: x = 1
+edge 4 12: x = 0
+edge 4 9: x = 0
+edge 5 17: x = 1
+edge 5 16: x = 0
+edge 5 15: x = 0
+edge 5 14: x = 0
+edge 5 13: x = 0
+edge 5 12: x = 0
+edge 5 11: x = 0
+edge 6 9: x = 1
+edge 7 10: x = 1
+edge 8 11: x = 0
+edge 8 10: x = 0
+\end{verbatim}
+\end{footnotesize}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Critical path problem}
+
+\subsection{Background}
+
+The {\it critical path problem} (CPP) is stated as follows. Let there
+be given a project $J$, which is a set of jobs (tasks, activities,
+etc.). Performing each job $i\in J$ requires time $t_i\geq 0$. Besides,
+over the set $J$ there is given a precedence relation
+$R\subseteq J\times J$, where $(i,j)\in R$ means that job $i$
+immediately precedes job $j$, i.e. performing job $j$ cannot start
+until job $i$ has been completely performed. The problem is to find
+starting times $x_i$ for each job $i\in J$, which satisfy to the
+precedence relation and minimize the total duration (makespan) of the
+project.
+
+The following is an example of the critical path problem:
+
+\bigskip
+
+\begin{center}
+\begin{tabular}{|c|l|c|c|}
+\hline
+Job&Desription&Time&Predecessors\\
+\hline
+A&Excavate&3&---\\
+B&Lay foundation&4&A\\
+C&Rough plumbing&3&B\\
+D&Frame&10&B\\
+E&Finish exterior&8&D\\
+F&Install HVAC&4&D\\
+G&Rough electric&6&D\\
+H&Sheet rock&8&C, E, F, G\\
+I&Install cabinets&5&H\\
+J&Paint&5&H\\
+K&Final plumbing&4&I\\
+L&Final electric&2&J\\
+M&Install flooring&4&K, L\\
+\hline
+\end{tabular}
+\end{center}
+
+\bigskip
+
+Obviously, the project along with the precedence relation can be
+represented as a directed graph $G=(J,R)$ called {\it project network},
+where each node $i\in J$ corresponds to a job, and arc
+$(i\rightarrow j)\in R$ means that job $i$ immediately precedes job
+$j$.\footnote{There exists another network representation of the
+critical path problem, where jobs correspond to arcs while nodes
+correspond to events introduced to express the precedence relation.
+That representation, however, is much less convenient than the one,
+where jobs are represented as nodes of the network.} The project network
+for the example above is shown on Fig.~4.
+
+\hspace*{.5in}
+\xymatrix
+{&&&C|3\ar[rd]&&I|5\ar[r]&K|4\ar[rd]&\\
+A|3\ar[r]&B|4\ar[rru]\ar[rd]&&E|8\ar[r]&H|8\ar[ru]\ar[rd]&&&M|4\\
+&&D|10\ar[ru]\ar[r]\ar[rd]&F|4\ar[ru]&&J|5\ar[r]&L|2\ar[ru]&\\
+&&&G|6\ar[ruu]&&&&\\
+}
+
+\medskip
+
+\noindent\hfil
+Fig.~4. An example of the project network.
+
+\newpage
+
+May note that the project network must be acyclic; otherwise, it would
+be impossible to satisfy to the precedence relation for any job that
+belongs to a cycle.
+
+The critical path problem can be naturally formulated as the following
+LP problem:
+
+\medskip
+
+\noindent
+\hspace{.5in}minimize
+$$z\eqno(19)$$
+\hspace{.5in}subject to
+$$x_i+t_i\leq z\ \ \ \hbox{for all}\ i\in J\ \ \ \ \eqno(20)$$
+$$x_i+t_i\leq x_j\ \ \ \hbox{for all}\ (i,j)\in R\eqno(21)$$
+$$x_i\geq 0\ \ \ \ \ \ \ \hbox{for all}\ i\in J\ \ \eqno(22)$$
+
+The inequality constraints (21), which are active in the optimal
+solution, define so called {\it critical path} having the following
+property: the minimal project duration $z$ can be decreased only by
+decreasing the times $t_j$ for jobs on the critical path, and delaying
+any critical job delays the entire project.
+
+\subsection{glp\_cpp --- solve critical path problem}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_cpp(glp_graph *G, int v_t, int v_es, int v_ls);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_cpp| solves the critical path problem represented
+in the form of the project network.
+
+The parameter \verb|G| is a pointer to the graph object, which
+specifies the project network. This graph must be acyclic. Multiple
+arcs are allowed being considered as single arcs.
+
+The parameter \verb|v_t| specifies an offset of the field of type
+\verb|double| in the vertex data block, which contains time $t_i\geq 0$
+needed to perform corresponding job $j\in J$. If \verb|v_t| $<0$, it is
+assumed that $t_i=1$ for all jobs.
+
+The parameter \verb|v_es| specifies an offset of the field of type
+\verb|double| in the vertex data block, to which the routine stores
+the {\it earliest start time} for corresponding job. If \verb|v_es|
+$<0$, this time is not stored.
+
+The parameter \verb|v_ls| specifies an offset of the field of type
+\verb|double| in the vertex data block, to which the routine stores
+the {\it latest start time} for corresponding job. If \verb|v_ls|
+$<0$, this time is not stored.
+
+The difference between the latest and earliest start times of some job
+is called its {\it time reserve}. Delaying a job within its time
+reserve does not affect the project duration, so if the time reserve is
+zero, the corresponding job is critical.
+
+\para{Returns}
+
+The routine \verb|glp_cpp| returns the minimal project duration, i.e.
+minimal time needed to perform all jobs in the project.
+
+\newpage
+
+\para{Example}
+
+The example program below solves the critical path problem shown on
+Fig.~4 by using the routine \verb|glp_cpp| and writes the solution
+found on the standard output.
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+typedef struct { double t, es, ls; } v_data;
+
+#define node(v) ((v_data *)((v)->data))
+
+int main(void)
+{ glp_graph *G;
+ int i;
+ double t, es, ef, ls, lf, total;
+ G = glp_create_graph(sizeof(v_data), 0);
+ glp_add_vertices(G, 13);
+ node(G->v[1])->t = 3; /* A: Excavate */
+ node(G->v[2])->t = 4; /* B: Lay foundation */
+ node(G->v[3])->t = 3; /* C: Rough plumbing */
+ node(G->v[4])->t = 10; /* D: Frame */
+ node(G->v[5])->t = 8; /* E: Finish exterior */
+ node(G->v[6])->t = 4; /* F: Install HVAC */
+ node(G->v[7])->t = 6; /* G: Rough elecrtic */
+ node(G->v[8])->t = 8; /* H: Sheet rock */
+ node(G->v[9])->t = 5; /* I: Install cabinets */
+ node(G->v[10])->t = 5; /* J: Paint */
+ node(G->v[11])->t = 4; /* K: Final plumbing */
+ node(G->v[12])->t = 2; /* L: Final electric */
+ node(G->v[13])->t = 4; /* M: Install flooring */
+ glp_add_arc(G, 1, 2); /* A precedes B */
+ glp_add_arc(G, 2, 3); /* B precedes C */
+ glp_add_arc(G, 2, 4); /* B precedes D */
+ glp_add_arc(G, 4, 5); /* D precedes E */
+ glp_add_arc(G, 4, 6); /* D precedes F */
+ glp_add_arc(G, 4, 7); /* D precedes G */
+ glp_add_arc(G, 3, 8); /* C precedes H */
+ glp_add_arc(G, 5, 8); /* E precedes H */
+ glp_add_arc(G, 6, 8); /* F precedes H */
+ glp_add_arc(G, 7, 8); /* G precedes H */
+ glp_add_arc(G, 8, 9); /* H precedes I */
+ glp_add_arc(G, 8, 10); /* H precedes J */
+ glp_add_arc(G, 9, 11); /* I precedes K */
+ glp_add_arc(G, 10, 12); /* J precedes L */
+ glp_add_arc(G, 11, 13); /* K precedes M */
+ glp_add_arc(G, 12, 13); /* L precedes M */
+ total = glp_cpp(G, offsetof(v_data, t), offsetof(v_data, es),
+ offsetof(v_data, ls));
+ printf("Minimal project duration is %.2f\n\n", total);
+ printf("Job Time ES EF LS LF\n");
+ printf("--- ------ ------ ------ ------ ------\n");
+ for (i = 1; i <= G->nv; i++)
+ { t = node(G->v[i])->t;
+ es = node(G->v[i])->es;
+ ef = es + node(G->v[i])->t;
+ ls = node(G->v[i])->ls;
+ lf = ls + node(G->v[i])->t;
+ printf("%3d %6.2f %s %6.2f %6.2f %6.2f %6.2f\n",
+ i, t, ls - es < 0.001 ? "*" : " ", es, ef, ls, lf);
+ }
+ glp_delete_graph(G);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+The output from the example program shown below includes job number,
+the time needed to perform a job, earliest start time (\verb|ES|),
+earliest finish time (\verb|EF|), latest start time (\verb|LS|), and
+latest finish time (\verb|LF|) for each job in the project. Critical
+jobs are marked by asterisks.
+
+\begin{footnotesize}
+\begin{verbatim}
+Minimal project duration is 46.00
+
+Job Time ES EF LS LF
+--- ------ ------ ------ ------ ------
+ 1 3.00 * 0.00 3.00 0.00 3.00
+ 2 4.00 * 3.00 7.00 3.00 7.00
+ 3 3.00 7.00 10.00 22.00 25.00
+ 4 10.00 * 7.00 17.00 7.00 17.00
+ 5 8.00 * 17.00 25.00 17.00 25.00
+ 6 4.00 17.00 21.00 21.00 25.00
+ 7 6.00 17.00 23.00 19.00 25.00
+ 8 8.00 * 25.00 33.00 25.00 33.00
+ 9 5.00 * 33.00 38.00 33.00 38.00
+ 10 5.00 33.00 38.00 35.00 40.00
+ 11 4.00 * 38.00 42.00 38.00 42.00
+ 12 2.00 38.00 40.00 40.00 42.00
+ 13 4.00 * 42.00 46.00 42.00 46.00
+\end{verbatim}
+\end{footnotesize}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\end{document}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Graph Optimization API Routines}
+
+\section{Maximum clique problem}
+
+\subsection{Background}
+
+The {\it maximum clique problem (MCP)} is a classic combinatorial
+optimization problem. Given an undirected graph $G=(V,E)$, where $V$ is
+a set of vertices, and $E$ is a set of edges, this problem is to find
+the largest {\it clique} $C\subseteq G$, i.e. the largest induced
+complete subgraph. A generalization of this problem is the {\it maximum
+weight clique problem (MWCP)}, which is to find a clique $C\subseteq G$
+of the largest weight $\displaystyle\sum_{v\in C}w(v)\rightarrow\max$,
+where $w(v)$ is a weight of vertex $v\in V$.
+
+An example of the maximum weight clique problem is shown on Fig.~5.
+
+\begin{figure}
+\noindent\hfil
+\begin{tabular}{c}
+{\xymatrix %@C=16pt
+{&&&{v_1}\ar@{-}[lllddd]\ar@{-}[llddddd]\ar@{-}[dddddd]
+\ar@{-}[rrrddd]&&&\\
+&{v_2}\ar@{-}[rrrr]\ar@{-}[rrrrdddd]\ar@{-}[rrddddd]\ar@{-}[dddd]&&&&
+{v_3}\ar@{-}[llllldd]\ar@{-}[lllldddd]\ar@{-}[dddd]&\\
+&&&&&&\\
+{v_4}\ar@{-}[rrrrrr]\ar@{-}[rrrddd]&&&&&&{v_5}\ar@{-}[lllddd]
+\ar@{-}[ldd]\\
+&&&&&&\\
+&{v_6}\ar@{-}[rrrr]&&&&{v_7}&\\
+&&&{v_8}&&&\\
+}}
+\end{tabular}
+\begin{tabular}{r@{\ }c@{\ }l}
+$w(v_1)$&=&3\\$w(v_2)$&=&4\\$w(v_3)$&=&8\\$w(v_4)$&=&1\\
+$w(v_5)$&=&5\\$w(v_6)$&=&2\\$w(v_7)$&=&1\\$w(v_8)$&=&3\\
+\end{tabular}
+
+\bigskip
+
+\begin{center}
+Fig.~5. An example of the maximum weight clique problem.
+\end{center}
+\end{figure}
+
+\subsection{glp\_wclique\_exact --- find maximum weight clique with
+exact algorithm}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_wclique_exact(glp_graph *G, int v_wgt, double *sol, int v_set);
+\end{verbatim}
+
+\description
+
+The routine {\tt glp\_wclique\_exact} finds a maximum weight clique in
+the specified undirected graph with the exact algorithm developed by
+Patric \"Osterg{\aa}rd.\footnote{P.~R.~J.~\"Osterg{\aa}rd, A new
+algorithm for the maximum-weight clique problem, Nordic J. of
+Computing, Vol.~8, No.~4, 2001, pp.~424--36.}
+
+The parameter {\tt G} is the program object, which specifies
+an undirected graph. Each arc $(x\rightarrow y)$ in {\tt G} is
+considered as edge $(x,y)$, self-loops are ignored, and multiple edges,
+if present, are replaced (internally) by simple edges.
+
+The parameter {\tt v\_wgt} specifies an offset of the field of type
+{\tt double} in the vertex data block, which contains a weight of
+corresponding vertex. Vertex weights must be integer-valued in the
+range $[0,$ {\tt INT\_MAX}$]$. If {\tt v\_wgt} $<0$, it is assumed that
+all vertices of the graph have the weight 1.
+
+\newpage
+
+The parameter {\tt sol} specifies a location, to which the routine
+stores the weight of the clique found (the clique weight is the sum
+of weights of all vertices included in the clique.) If {\tt sol} is
+{\tt NULL}, the solution is not stored.
+
+The parameter {\tt v\_set} specifies an offset of the field of type
+{\tt int} in the vertex data block, to which the routines stores a
+vertex flag: 1 means that the corresponding vertex is included in the
+clique found, and 0 otherwise. If {\tt v\_set} $<0$, vertex flags are
+not stored.
+
+\returns
+
+\begin{retlist}
+0 & Optimal solution found.\\
+
+\verb|GLP_EDATA| & Unable to start the search, because some vertex
+weights are either not integer-valued or out of range. This code is
+also returned if the sum of weights of all vertices exceeds
+{\tt INT\_MAX}. \\
+\end{retlist}
+
+\para{Notes}
+
+1. The routine {\it glp\_wclique\_exact} finds exact solution. Since
+both MCP and MWCP problems are NP-complete, the algorithm may require
+exponential time in worst cases.
+
+2. Internally the specified graph is converted to an adjacency matrix
+in {\it dense} format. This requires about $|V|^2/16$ bytes of memory,
+where $|V|$ is the number of vertices in the graph.
+
+\para{Example}
+
+The example program shown below reads a MWCP instance in DIMACS
+clique/coloring format from file `\verb|sample.clq|', finds the clique
+of largest weight, and writes the solution found on the standard
+output.
+
+\newpage
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+typedef struct { double wgt; int set; } v_data;
+
+#define vertex(v) ((v_data *)((v)->data))
+
+int main(void)
+{ glp_graph *G;
+ glp_vertex *v;
+ int i, ret;
+ double sol;
+ G = glp_create_graph(sizeof(v_data), 0);
+ glp_read_ccdata(G, offsetof(v_data, wgt), "sample.clq");
+ ret = glp_wclique_exact(G, offsetof(v_data, wgt), &sol,
+ offsetof(v_data, set));
+ printf("ret = %d; sol = %g\n", ret, sol);
+ for (i = 1; i <= G->nv; i++)
+ { v = G->v[i];
+ printf("vertex %d: weight = %g, flag = %d\n",
+ i, vertex(v)->wgt, vertex(v)->set);
+ }
+ glp_delete_graph(G);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+For the example shown on Fig.~5 the data file may look like follows:
+
+\begin{footnotesize}
+\begin{verbatim}
+c sample.clq
+c
+c This is an example of the maximum weight clique
+c problem in DIMACS clique/coloring format.
+c
+p edge 8 16
+n 1 3
+n 2 4
+n 3 8
+n 5 5
+n 6 2
+n 8 3
+e 1 4
+e 1 5
+e 1 6
+e 1 8
+e 2 3
+e 2 6
+e 2 7
+e 2 8
+e 3 4
+e 3 6
+e 3 7
+e 4 5
+e 4 8
+e 5 7
+e 5 8
+e 6 7
+c
+c eof
+\end{verbatim}
+\end{footnotesize}
+
+The corresponding output from the example program is the following:
+
+\begin{footnotesize}
+\begin{verbatim}
+Reading graph from `sample.clq'...
+Graph has 8 vertices and 16 edges
+28 lines were read
+ret = 0; sol = 15
+vertex 1: weight = 3, flag = 0
+vertex 2: weight = 4, flag = 1
+vertex 3: weight = 8, flag = 1
+vertex 4: weight = 1, flag = 0
+vertex 5: weight = 5, flag = 0
+vertex 6: weight = 2, flag = 1
+vertex 7: weight = 1, flag = 1
+vertex 8: weight = 3, flag = 0
+\end{verbatim}
+\end{footnotesize}
+
+\end{document}