<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">% pscript.tex, a LaTeX file with PostScript graphics
\documentclass[10pt]{article}
\usepackage[pctex32]{graphics}
\setlength{\parindent}{12pt}
\setlength{\parskip}{0pt}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand\lecture{6} %% Lecture number
\renewcommand\title{Preflow-push algorithms}   %% Title of lecture
\renewcommand\author{Vladimir Kolmogorov}  %% name of scribe
\renewcommand\date{2/10/00}    %% Date of lecture
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\renewcommand\maketitle{
\begin{flushleft}
{\large
\textsf{CS664 Lecture \#\lecture \hfill \title \hfill \date}}\\
\textsf{Scribe: \author}\hfill\textsf{Lecturer: Jon Kleinberg}\\
\hrulefill
\end{flushleft}}

\newtheorem{definition}{Definition}
\newtheorem{fact}{Fact}
\newcommand{\dashline}{\begin{picture}(300,0)(0,0)
	\multiput(0,0)(10,0){30}{\line(1,0){5}}
	\end{picture}}

\begin{document}

\maketitle

\section{Introduction}
Last time we introduced the maxflow-mincut problem and the augmenting
path algorithm for its solution.

The maxflow problem is the following problem: given graph $G_f$ with
nodes $s$ and $t$, which are called the source and the sink, respectively,
find a flow of a maximum value from $s$ to $t$ satisfying capacity
constraints and flow conservation constraints in all nodes except
$s$ and $t$.

The picture below shows a simple graph $G$ with some flow $f$ and
a residual graph $G_f$ for this flow. A residual graph for a flow $f$
basically tells how we can update this flow. Saturated edges, for
example, go away in a residual graph.

{\setlength{\parindent}{-20pt}

\begin{picture}(300,100)(0,0)
% graph
\put (20,40) {\circle* {10}}
\put (100,80) {\circle* {10}}
\put (100,0) {\circle* {10}}
\put (180,40) {\circle* {10}}

\put (10,40) {$s$}
\put (187,40) {$t$}

\put (20,40) {\vector (2,1) {75}}
\put (40,62) {\scriptsize 20(12)}
\put (20,40) {\vector (2,-1) {75}}
\put (40,13) {\scriptsize 10(9)}
\put (100,80) {\vector (2,-1) {75}}
\put (140,62) {\scriptsize 10(8)}
\put (100,0) {\vector (2,1) {75}}
\put (140,13) {\scriptsize 20(13)}
\put (100,80) {\vector (0,-1) {75}}
\put (100,40) {\scriptsize 20(4)}

%residual graph
\put (220,40) {\circle* {10}}
\put (300,80) {\circle* {10}}
\put (300,0) {\circle* {10}}
\put (380,40) {\circle* {10}}

\put (220,43) {\vector (2,1) {75}}
\put (250,62) {\scriptsize 8}
\put (300,78) {\vector (-2,-1) {75}}
\put (260,52) {\scriptsize 12}
\put (220,37) {\vector (2,-1) {75}}
\put (250,13) {\scriptsize 1}
\put (300,2) {\vector (-2,1) {75}}
\put (260,23) {\scriptsize 9}
\put (380,38) {\vector (-2,1) {76}}
\put (333,52) {\scriptsize 8}
\put (300,83) {\vector (2,-1) {77}}
\put (343,62) {\scriptsize 2}
\put (380,42) {\vector (-2,-1) {76}}
\put (333,23) {\scriptsize 13}
\put (300,-3) {\vector (2,1) {77}}
\put (343,13) {\scriptsize 7}
\put (298,80) {\vector (0,-1) {75}}
\put (288,40) {\scriptsize 16}
\put (302,0) {\vector (0,1) {75}}
\put (303,40) {\scriptsize 4}
\end{picture}

}

{\setlength{\parskip}{12pt}
An augmenting path in the residual graph is any simple path from the source to the sink
every edge of which has nonzero capacity. The augmenting path algorithm is quite
simple: find an augmenting path in the residual graph and augment it (push the
amount of flow equal to the minimum capacity of edges in the path) until there is
no such a path.
}

The minimum cut problem is the problem of finding a cut of a minimum cost.
A cut is a partitioning of vertices into two sets $S$ and $T$ such that
$s \in S$ and $t \in T$.

These problems are closely connected: given a maximum flow $f$ it is very
easy to find a minimum cut. The partitioning is given as follows:

$S$ are all nodes reachable from $s$ in the residual graph $G_f$

$T$ are all nodes not reachable from $s$ in the residual graph $G_f$

\section{Push-relabel algorithm}
\subsection{Definitions}
Push-relabel (or preflow-push) algorithm is another algorithm for finding
maximum flow quite different from the augmenting path algorithm. It was
developed by Goldberg (1986), Goldberg and Tarjan (1988). There was also
an earlier work by Karzanov (1970's) in the Soviet Union.

The algorithm works with preflows rather than flows. The preflow is
updated iteratively until it becomes a flow.

\begin{definition}
Preflow is an assignment $f$ of non-negative numbers to edges satisfying two
properties:
\begin{itemize}
	\item Capacity condition: for every edge $e \in E(G)$ \quad $f(e) \le c(e)$
	\item Preflow condition: for every node v $\in$ V(G) other than s and t \quad
		$f^{in}(v) \ge f^{out}(v)$
\end{itemize}
\end{definition}

where $f^{in}(v)$ and $f^{out}(v)$ are the amounts of flow coming into $v$ and out of
$v$, respectively. Note that the flow condition was $f^{in}(v) = f^{out}(v)$, $v \ne s, t$.

The residual graph for a preflow is defined in the same way as for a flow.

Another important notion is a notion of valid labelling.

\begin{definition}
A valid labelling of $G_f$ is a function h: $V$ $\rightarrow$ integer numbers
such that
$$ h(s) = n $$
$$ h(t) = 0 $$
$$ \forall vw \in E(G_f) \quad h(v) \le h(w)+1 $$
\end{definition}

$h(v)$ can be viewed as a height of a node. The last condition means that edges
can not go downhill too steeply.

\begin{picture}(300,80)(0,0)
\multiput (0,0)(0,20){4}{\dashline}
\put (60,20){\circle* {5}}
\put (60,25){$v$}
\put (80,0){\circle* {5}}
\put (80,5){$w$}
\put (60,20){\vector(1,-1){19}}
\put (120,20){\circle* {5}}
\put (120,25){$v$}
\put (140,20){\circle* {5}}
\put (140,25){$w$}
\put (120,20){\vector(1,0){19}}
\put (180,20){\circle* {5}}
\put (175,25){$v$}
\put (200,60){\circle* {5}}
\put (200,65){$w$}
\put (180,20){\vector(1,2){19}}
\end{picture}

{\setlength{\parskip}{12pt}
Note that not every flow (and preflow) has a valid labelling as it follows from
the following fact.
}

\begin{fact}
If $f$ is a flow that has a valid labelling $h$, then $f$ is a max flow.
\end{fact}

$Proof.$ In order to prove this we need to prove that there is no augmenting
path in the residual graph $G_f$. Suppose there is one: $v_0=s$, $v_1$, \ldots, $v_k=t$.
Note that the number of nodes in this path is at most the number of nodes in
the graph $G$: $k+1 \le n$. Since there is a valid labelling of the residual
graph, the height of nodes is decreased by at most 1 along the path;
thus we have $h(v_i) \ge h(v_0) - i = n - i$, $h(t) = n - k &gt; 0$ - contradiction.

Consider some preflow $f$ which has a valid labelling $h$. According to the
pigeonhole principle, there should be a gap in heights - an integer $h_g$, $0&lt;h_g&lt;n$,
so that no node in $G$ has a height $h_g$. This gap defines an $s-t$ cut in the
obvious way; this cut is a minimum cut if $f$ is a flow.

\subsection{Algorithm}
At the high level the push-relabel algorithm can be written as follows.

\begin{bf}
\begin{center}
iterate through pairs ($f$, $h$), where $f$ is a preflow and \\
$h$ is a valid labelling, until $f$ becomes a flow.
\end{center}
\end{bf}

\subsubsection{Initialization}
The push-relabel algorithm cannot be initialized with the zero flow
as the augmenting path algorithm (if zero flow had a valid labelling
it would be a maximum flow). The easy way to set a preflow with a valid
labelling is the following. Let $f(e)=c(e)$ for all edges $e=sv$ out of
the source and $f(e)=0$ for all other edges, then $f$ is clearly a preflow.
Let $h(s)=n$ and $h(v)=0$ for all other nodes, then $h$ is a valid labelling
for $f$ since all edges out of the source are saturated.
\subsubsection{Iteration}
If $f$ is not a flow then there exists an active node $v$, $v \ne s,t$, with
a flow excess: $f^{in}(v)&gt;f^{out}(v)$. One iteration consists of two steps:

\begin{tabbing}
1. \= $while$ \= \\
		  \&gt;\&gt; there exists an edge $vw$ in $G_f$ s.t. $h(v)=h(w)+1$ \\
		  \&gt;\&gt; push flow on $vw$ (up to the
			 min\{residual capacity of $vw$, $f^{in}(v)-f^{out}(v)\}$) \\
		  \&gt;\&gt; (if $vw$ becomes saturated then this push is called a saturated push \\
		  \&gt;\&gt; otherwise it's a nonsaturating push) \\
   \&gt; $end$ $while$
\end{tabbing}

This operation can result in two outcomes:
\begin{itemize}
	\item the flow excess in $v$ is exhausted: $f^{in}(v)=f^{out}(v)$, the node
		became inactive - then we are done
	\item $v$ is still active but no flow can be pushed out of $v$ without 
		violating capacity constraint. In that case we relabel $v$ - "lift" it:
\end{itemize}

2. increase $h(v)$ to be $\min_{vw \in E_f}{[1+h(w)]}$

Note that these operations preserve preflow and valid labelling conditions.

\section{Analysis}
Since heights of nodes cannot decrease it suffices to show that they are bounded
from above in order to prove that the algorithm will terminate.

Consider some active node $v$ with a flow excess. The crucial observation is that
there is a flow path from the source to $v$. Hence, there is a backward path in
the residual graph $G_f$ consisting of no more than n nodes: $v_0=v$, $v_1$, \ldots,
$v_k=s$, $k+1 \le n$. The height of nodes in the path is decreased by at most 1 along
the path; thus we have $h(v_i) \ge h(v_0) - i = h(v) - i$, $h(v) \le h(s) + k \le 2n-1$

This bound is clearly also true for inactive nodes since only active nodes are relabeled.
Thus we proved the inequality $h(v) \le 2n-1$ for all nodes in $G$.

Thus, each node can be relabeled at most $2n$ times, so the total number of relabels is
$O(n^2)$. The number of pushes between any two relabels is at most $m$ (since no edge
can be pushed twice with the same labelling), so the total number of pushes is $O(mn^2)$.
Note that the running time depends on the particular implementation and data structures
used.

An informal way to compare the push-relabel algorithm with the augmenting path algorithm
is the following. The important difference between them is that the former needs constant
time for update operation while the latter requires finding an augmenting path which takes
$O(m)$ time, so usually the former is faster.

\section{Selection of nodes}
The basic algorithm described above tells nothing about the order of nodes processing.
Meanwhile, this order affects the perfomance of the algorithm greatly. Below are several
possibilities of selection of nodes:

\begin{itemize}
	\item LIFO order (stack)
	\item order based on maximum imbalance
	\item lowest active node
	\item FIFO order (queue)
	\item highest active node
\end{itemize}

The code written by Goldberg uses FIFO order (F\_PRF, Q\_PRF) and
highest active node order (H\_PRF, M\_PRF) for which there are better
theoretical bounds (for example, highest active node order yields
in $O(n^3)$ operations). To implement these orders it is important
to maintain nodes in the implicit data structure; for FIFO order
this data structure is a queue and for highest active node order
it is a priority queue.

\section{Heuristics}
To make the code run faster some heuristic optimizations are used. The
idea behind them is to "fast forward" the height function preserving
a valid labelling.

\subsection{Global relabelling}
Suppose at some step the nodes look like as shown in the picture, then
we can relabel them without violating a valid labelling. In general,
such relabelling can be found by the backward breadth first search.
However, breadth first search requires $O(m)$ operations. Thus, in order
not to negatively affect the running time we can apply global relabelling
every $O(m)$ operations.

\begin{picture}(300,120)(0,0)

\put (20,80){\circle* {5}}  \put (20,85){0}
\put (40,60){\circle* {5}}  \put (40,65){0}
\put (60,80){\circle* {5}}  \put (60,85){0}
\put (100,80){\circle* {5}} \put (100,85){0}
\put (120,60){\circle* {5}} \put (120,65){0}
\put (140,80){\circle* {5}} \put (140,85){0}
\put (80, 40){\circle* {5}} \put (80,45){0}
\put (20,80) {\vector (1,-1){19}}
\put (60,80) {\vector (-1,-1){19}}
\put (100,80) {\vector (1,-1){19}}
\put (140,80) {\vector (-1,-1){19}}
\put (40, 60){\vector (2,-1){39}}
\put (120, 60){\vector (-2,-1){39}}

\put (220,80){\circle* {5}}  \put (220,85){2}
\put (240,60){\circle* {5}}  \put (240,65){1}
\put (260,80){\circle* {5}}  \put (260,85){2}
\put (300,80){\circle* {5}} \put (300,85){2}
\put (320,60){\circle* {5}} \put (320,65){1}
\put (340,80){\circle* {5}} \put (340,85){2}
\put (280, 40){\circle* {5}} \put (280,45){0}
\put (220,80) {\vector (1,-1){19}}
\put (260,80) {\vector (-1,-1){19}}
\put (300,80) {\vector (1,-1){19}}
\put (340,80) {\vector (-1,-1){19}}
\put (240, 60){\vector (2,-1){39}}
\put (320, 60){\vector (-2,-1){39}}

\put (170, 60) {$\Longrightarrow$}

\end{picture}

\subsection {Gap relabelling}
Another heuristic for fast increase of heights is the following. At each
step there is a gap in heights which defines an $s-t$ cut; initially all
nodes except the source are on the sink side of the cut. As the algorithm
proceeds heights of nodes are increasing, and at some moment a set of nodes
can be lifted above the gap. Then we can lift these nodes to the height $n$
still preserving a valid labelling; this operation is called gap relabelling.

Note that at this moment we can infer that these nodes (and nodes with a height
at least $n$) will be on the source side of a cut in the final solution. It is
another difference from the augmenting path algorithm in which one can tell
nothing about a min cut until the algorithm terminates.

\begin{picture}(300,140)(0,0)
\multiput (0,0)(0,20){7}{\dashline}
\put (0,40){\line (1,0){300}}
\put (40,120){\circle* {5}}
\put (40,125) {$s$}
\put (60,80){\circle* {5}}
\put (60,120){\circle* {5}}
\put (60,80){\vector(0,1){39}}
\put (80,60){\circle* {5}}
\put (80,120){\circle* {5}}
\put (80,60){\vector(0,1){59}}
\put (100,100){\circle* {5}}
\put (100,120){\circle* {5}}
\put (100,100){\vector(0,1){19}}
\put (120,20){\circle* {5}}
\put (140,20){\circle* {5}}
\put (160,0){\circle* {5}}
\put (180,100){\circle* {5}}
\put (180,120){\circle* {5}}
\put (180,100){\vector(0,1){19}}
\put (200,0){\circle* {5}}
\put (200,5) {$t$}
\end{picture}

{\setlength{\parskip}{12pt}
In the Goldberg implementation M\_PRF and F\_PRF use global relabelling and gap
relabelling while H\_PRF and Q\_PRF use only global relabelling.
}

\end{document}
</pre></body></html>