1365 lines
50 KiB
TeX
1365 lines
50 KiB
TeX
\chapter{Flows and cuts}
|
||
|
||
In this chapter, we will focus on the following
|
||
problems in a directed, weighted graph
|
||
where a starting node and a ending node is given:
|
||
|
||
\begin{itemize}
|
||
\item \key{Finding a maximum flow}:
|
||
What is the maximum amount of flow we can
|
||
deliver
|
||
from the starting node to the ending node?
|
||
\item \key{Finding a minimum cut}:
|
||
What is a minimum-weight set of edges
|
||
that separates the starting node and the ending node?
|
||
\end{itemize}
|
||
|
||
It turns out that these problems correspond to
|
||
each other, and we can solve them simultaneously
|
||
using the same algorithm.
|
||
|
||
As an example, we will use the following graph
|
||
where node 1 is the starting node and node 6
|
||
is the ending node:
|
||
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.9]
|
||
\node[draw, circle] (1) at (1,2) {$1$};
|
||
\node[draw, circle] (2) at (3,3) {$2$};
|
||
\node[draw, circle] (3) at (5,3) {$3$};
|
||
\node[draw, circle] (4) at (7,2) {$6$};
|
||
\node[draw, circle] (5) at (3,1) {$4$};
|
||
\node[draw, circle] (6) at (5,1) {$5$};
|
||
\path[draw,thick,->] (1) -- node[font=\small,label=5] {} (2);
|
||
\path[draw,thick,->] (2) -- node[font=\small,label=6] {} (3);
|
||
\path[draw,thick,->] (3) -- node[font=\small,label=5] {} (4);
|
||
\path[draw,thick,->] (1) -- node[font=\small,label=below:4] {} (5);
|
||
\path[draw,thick,->] (5) -- node[font=\small,label=below:1] {} (6);
|
||
\path[draw,thick,->] (6) -- node[font=\small,label=below:2] {} (4);
|
||
\path[draw,thick,<-] (2) -- node[font=\small,label=left:3] {} (5);
|
||
\path[draw,thick,->] (3) -- node[font=\small,label=left:8] {} (6);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
\subsubsection{Maximum flow}
|
||
|
||
\index{flow}
|
||
\index{maximum flow}
|
||
|
||
A \key{maximum flow} is a flow from the
|
||
starting node to the ending node whose
|
||
total amount is as large as possible.
|
||
The weight of each edge is a capacity that
|
||
determines the maximum amount of flow that
|
||
can go through the edge.
|
||
In all nodes, except for the starting node
|
||
and the ending node,
|
||
the amount of incoming and outgoing flow
|
||
must be the same.
|
||
|
||
A maximum flow for the example graph
|
||
is as follows:
|
||
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.9]
|
||
\node[draw, circle] (1) at (1,2) {$1$};
|
||
\node[draw, circle] (2) at (3,3) {$2$};
|
||
\node[draw, circle] (3) at (5,3) {$3$};
|
||
\node[draw, circle] (4) at (7,2) {$6$};
|
||
\node[draw, circle] (5) at (3,1) {$4$};
|
||
\node[draw, circle] (6) at (5,1) {$5$};
|
||
\path[draw,thick,->] (1) -- node[font=\small,label=3/5] {} (2);
|
||
\path[draw,thick,->] (2) -- node[font=\small,label=6/6] {} (3);
|
||
\path[draw,thick,->] (3) -- node[font=\small,label=5/5] {} (4);
|
||
\path[draw,thick,->] (1) -- node[font=\small,label=below:4/4] {} (5);
|
||
\path[draw,thick,->] (5) -- node[font=\small,label=below:1/1] {} (6);
|
||
\path[draw,thick,->] (6) -- node[font=\small,label=below:2/2] {} (4);
|
||
\path[draw,thick,<-] (2) -- node[font=\small,label=left:3/3] {} (5);
|
||
\path[draw,thick,->] (3) -- node[font=\small,label=left:1/8] {} (6);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
The notation $v/k$ means
|
||
that amount of the flow through the edge is $v$
|
||
and the capacity of the edge is $k$.
|
||
For each edge, it is required that $v \le k$.
|
||
In this graph, the size of a maximum flow is 7
|
||
because the outgoing flow from the starting node is $3+4=7$,
|
||
and the incoming flow to the ending node is $5+2=7$.
|
||
|
||
Note that in each intermediate node,
|
||
the incoming flow and the outgoing flow are equally large.
|
||
For example, in node 2, the incoming flow is $3+3=6$
|
||
from nodes 1 and 4,
|
||
and the outgoing flow is $6$ to node 3.
|
||
|
||
\subsubsection{Minimum cut}
|
||
|
||
\index{cut}
|
||
\index{minimum cut}
|
||
|
||
A \key{minimum cut} is a set of edges
|
||
whose removal separates the starting node from the ending node,
|
||
and whose total weight is as small as possible.
|
||
A cut divides the graph into two components,
|
||
one containing the starting node and the other
|
||
containing the ending node.
|
||
|
||
A minimum cut for the example graph is as follows:
|
||
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.9]
|
||
\node[draw, circle] (1) at (1,2) {$1$};
|
||
\node[draw, circle] (2) at (3,3) {$2$};
|
||
\node[draw, circle] (3) at (5,3) {$3$};
|
||
\node[draw, circle] (4) at (7,2) {$6$};
|
||
\node[draw, circle] (5) at (3,1) {$4$};
|
||
\node[draw, circle] (6) at (5,1) {$5$};
|
||
\path[draw,thick,->] (1) -- node[font=\small,label=5] {} (2);
|
||
\path[draw,thick,->] (2) -- node[font=\small,label=6] {} (3);
|
||
\path[draw,thick,->] (3) -- node[font=\small,label=5] {} (4);
|
||
\path[draw,thick,->] (1) -- node[font=\small,label=below:4] {} (5);
|
||
\path[draw,thick,->] (5) -- node[font=\small,label=below:1] {} (6);
|
||
\path[draw,thick,->] (6) -- node[font=\small,label=below:2] {} (4);
|
||
\path[draw,thick,<-] (2) -- node[font=\small,label=left:3] {} (5);
|
||
\path[draw,thick,->] (3) -- node[font=\small,label=left:8] {} (6);
|
||
|
||
\path[draw=red,thick,-,line width=2pt] (4-.3,3-.3) -- (4+.3,3+.3);
|
||
\path[draw=red,thick,-,line width=2pt] (4-.3,3+.3) -- (4+.3,3-.3);
|
||
\path[draw=red,thick,-,line width=2pt] (4-.3,1-.3) -- (4+.3,1+.3);
|
||
\path[draw=red,thick,-,line width=2pt] (4-.3,1+.3) -- (4+.3,1-.3);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
In this cut, the first component contains nodes $\{1,2,4\}$,
|
||
and the second component contains nodes $\{3,5,6\}$.
|
||
The weight of the cut is 7,
|
||
because it consists of edges
|
||
$2 \rightarrow 3$ and $4 \rightarrow 5$,
|
||
and the total weight of the edges is $6+1=7$.
|
||
\\\\
|
||
It is not a coincidence that
|
||
both the size of the maximum flow and
|
||
the weight of the minimum cut is 7
|
||
in the example graph.
|
||
It turns out that a maximum flow and
|
||
a minimum cut are \emph{always} of equal size,
|
||
so the concepts are two sides of the same coin.
|
||
|
||
Next we will discuss the Ford–Fulkerson
|
||
algorithm that can be used for finding
|
||
a maximum flow and a minimum cut in a graph.
|
||
The algorithm also helps us to understand
|
||
\emph{why} they are equally large.
|
||
|
||
\section{Ford–Fulkerson algorithm}
|
||
|
||
\index{Ford–Fulkerson algorithm}
|
||
|
||
The \key{Ford–Fulkerson algorithm} finds
|
||
a maximum flow in a graph.
|
||
The algorithm begins with an empty flow,
|
||
and at each step finds a path in the graph
|
||
that generates more flow.
|
||
Finally, when the algorithm can't extend the flow
|
||
anymore, it terminates and a maximum flow has been found.
|
||
|
||
The algorithm uses a special representation
|
||
for the graph where each original edge has a reverse
|
||
edge in another direction.
|
||
The weight of each edge indicates how much more flow
|
||
we could route through it.
|
||
Initially, the weight of each original edge
|
||
equals the capacity of the edge,
|
||
and the weight of each reverse edge is zero.
|
||
|
||
\begin{samepage}
|
||
The new representation for the example graph is as follows:
|
||
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.9,label distance=-2mm]
|
||
\node[draw, circle] (1) at (1,1.3) {$1$};
|
||
\node[draw, circle] (2) at (3,2.6) {$2$};
|
||
\node[draw, circle] (3) at (5,2.6) {$3$};
|
||
\node[draw, circle] (4) at (7,1.3) {$6$};
|
||
\node[draw, circle] (5) at (3,0) {$4$};
|
||
\node[draw, circle] (6) at (5,0) {$5$};
|
||
|
||
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=5] {} (2);
|
||
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=below:0] {} (1);
|
||
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=6] {} (3);
|
||
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=below:0] {} (2);
|
||
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=5] {} (4);
|
||
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:0] {} (3);
|
||
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=4] {} (5);
|
||
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=below:0] {} (1);
|
||
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=1] {} (6);
|
||
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=below:0] {} (5);
|
||
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=2] {} (4);
|
||
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:0] {} (6);
|
||
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=left:3] {} (2);
|
||
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=right:0] {} (5);
|
||
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=right:8] {} (6);
|
||
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=left:0] {} (3);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
\end{samepage}
|
||
|
||
\subsubsection{Algoritmin toiminta}
|
||
|
||
The Ford–Fulkerson algorithm finds at each step
|
||
a path from the starting node to the ending node
|
||
where each edge has a positive weight.
|
||
If there are more than one possible paths,
|
||
we can choose any of them.
|
||
|
||
In the example graph, we can choose, say, the following path:
|
||
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.9,label distance=-2mm]
|
||
\node[draw, circle] (1) at (1,1.3) {$1$};
|
||
\node[draw, circle] (2) at (3,2.6) {$2$};
|
||
\node[draw, circle] (3) at (5,2.6) {$3$};
|
||
\node[draw, circle] (4) at (7,1.3) {$6$};
|
||
\node[draw, circle] (5) at (3,0) {$4$};
|
||
\node[draw, circle] (6) at (5,0) {$5$};
|
||
|
||
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=5] {} (2);
|
||
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=below:0] {} (1);
|
||
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=6] {} (3);
|
||
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=below:0] {} (2);
|
||
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=5] {} (4);
|
||
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:0] {} (3);
|
||
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=4] {} (5);
|
||
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=below:0] {} (1);
|
||
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=1] {} (6);
|
||
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=below:0] {} (5);
|
||
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=2] {} (4);
|
||
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:0] {} (6);
|
||
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=left:3] {} (2);
|
||
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=right:0] {} (5);
|
||
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=right:8] {} (6);
|
||
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=left:0] {} (3);
|
||
|
||
\path[draw=red,thick,->,line width=2pt] (1) edge [bend left=10] (2);
|
||
\path[draw=red,thick,->,line width=2pt] (2) edge [bend left=10] (3);
|
||
\path[draw=red,thick,->,line width=2pt] (3) edge [bend left=10] (6);
|
||
\path[draw=red,thick,->,line width=2pt] (6) edge [bend left=10] (4);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
After choosing the path, the flow increases by $x$ units
|
||
where $x$ is the smallest weight of an edge in the path.
|
||
In addition, the weight of each edge in the path
|
||
decreases by $x$, and the weight of each reverse edge
|
||
increases by $x$.
|
||
|
||
In the above path, the weights of the
|
||
edges are 5, 6, 8 and 2.
|
||
The minimum weight is 2,
|
||
so the flow increases by 2
|
||
and the new graph is as follows:
|
||
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.9,label distance=-2mm]
|
||
\node[draw, circle] (1) at (1,1.3) {$1$};
|
||
\node[draw, circle] (2) at (3,2.6) {$2$};
|
||
\node[draw, circle] (3) at (5,2.6) {$3$};
|
||
\node[draw, circle] (4) at (7,1.3) {$6$};
|
||
\node[draw, circle] (5) at (3,0) {$4$};
|
||
\node[draw, circle] (6) at (5,0) {$5$};
|
||
|
||
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=3] {} (2);
|
||
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=below:2] {} (1);
|
||
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=4] {} (3);
|
||
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=below:2] {} (2);
|
||
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=5] {} (4);
|
||
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:0] {} (3);
|
||
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=4] {} (5);
|
||
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=below:0] {} (1);
|
||
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=1] {} (6);
|
||
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=below:0] {} (5);
|
||
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=0] {} (4);
|
||
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:2] {} (6);
|
||
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=left:3] {} (2);
|
||
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=right:0] {} (5);
|
||
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=right:6] {} (6);
|
||
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=left:2] {} (3);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
The idea is that increasing the flow decreases the amount of
|
||
flow that can go through the edges in the future.
|
||
On the other hand, it is possible to adjust the
|
||
amount of the flow later
|
||
using the reverse edges if it turns out that
|
||
we should route the flow in another way.
|
||
|
||
The algorithm increases the flow as long as
|
||
there is a path from the starting node
|
||
to the ending node through positive edges.
|
||
In the current example, our next path can be as follows:
|
||
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.9,label distance=-2mm]
|
||
\node[draw, circle] (1) at (1,1.3) {$1$};
|
||
\node[draw, circle] (2) at (3,2.6) {$2$};
|
||
\node[draw, circle] (3) at (5,2.6) {$3$};
|
||
\node[draw, circle] (4) at (7,1.3) {$6$};
|
||
\node[draw, circle] (5) at (3,0) {$4$};
|
||
\node[draw, circle] (6) at (5,0) {$5$};
|
||
|
||
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=3] {} (2);
|
||
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=below:2] {} (1);
|
||
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=4] {} (3);
|
||
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=below:2] {} (2);
|
||
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=5] {} (4);
|
||
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:0] {} (3);
|
||
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=4] {} (5);
|
||
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=below:0] {} (1);
|
||
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=1] {} (6);
|
||
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=below:0] {} (5);
|
||
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=0] {} (4);
|
||
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:2] {} (6);
|
||
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=left:3] {} (2);
|
||
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=right:0] {} (5);
|
||
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=right:6] {} (6);
|
||
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=left:2] {} (3);
|
||
|
||
\path[draw=red,thick,->,line width=2pt] (1) edge [bend left=10] (5);
|
||
\path[draw=red,thick,->,line width=2pt] (5) edge [bend left=10] (2);
|
||
\path[draw=red,thick,->,line width=2pt] (2) edge [bend left=10] (3);
|
||
\path[draw=red,thick,->,line width=2pt] (3) edge [bend left=10] (4);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
The minimum weight in this path is 3,
|
||
so the path increases the flow by 3,
|
||
and the total amount of the flow after
|
||
processing the path is 5.
|
||
|
||
\begin{samepage}
|
||
The new graph will be as follows:
|
||
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.9,label distance=-2mm]
|
||
\node[draw, circle] (1) at (1,1.3) {$1$};
|
||
\node[draw, circle] (2) at (3,2.6) {$2$};
|
||
\node[draw, circle] (3) at (5,2.6) {$3$};
|
||
\node[draw, circle] (4) at (7,1.3) {$6$};
|
||
\node[draw, circle] (5) at (3,0) {$4$};
|
||
\node[draw, circle] (6) at (5,0) {$5$};
|
||
|
||
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=3] {} (2);
|
||
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=below:2] {} (1);
|
||
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=1] {} (3);
|
||
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=below:5] {} (2);
|
||
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=2] {} (4);
|
||
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:3] {} (3);
|
||
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=1] {} (5);
|
||
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=below:3] {} (1);
|
||
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=1] {} (6);
|
||
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=below:0] {} (5);
|
||
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=0] {} (4);
|
||
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:2] {} (6);
|
||
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=left:0] {} (2);
|
||
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=right:3] {} (5);
|
||
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=right:6] {} (6);
|
||
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=left:2] {} (3);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
\end{samepage}
|
||
|
||
We still need two more steps before we have reached a maximum flow.
|
||
For example, we can choose the paths
|
||
$1 \rightarrow 2 \rightarrow 3 \rightarrow 6$ and
|
||
$1 \rightarrow 4 \rightarrow 5 \rightarrow 3 \rightarrow 6$.
|
||
Both paths increase the flow by 1,
|
||
and the final graph is as follows:
|
||
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.9,label distance=-2mm]
|
||
\node[draw, circle] (1) at (1,1.3) {$1$};
|
||
\node[draw, circle] (2) at (3,2.6) {$2$};
|
||
\node[draw, circle] (3) at (5,2.6) {$3$};
|
||
\node[draw, circle] (4) at (7,1.3) {$6$};
|
||
\node[draw, circle] (5) at (3,0) {$4$};
|
||
\node[draw, circle] (6) at (5,0) {$5$};
|
||
|
||
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=2] {} (2);
|
||
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=below:3] {} (1);
|
||
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=0] {} (3);
|
||
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=below:6] {} (2);
|
||
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=0] {} (4);
|
||
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:5] {} (3);
|
||
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=0] {} (5);
|
||
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=below:4] {} (1);
|
||
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=0] {} (6);
|
||
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=below:1] {} (5);
|
||
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=0] {} (4);
|
||
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:2] {} (6);
|
||
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=left:0] {} (2);
|
||
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=right:3] {} (5);
|
||
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=right:7] {} (6);
|
||
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=left:1] {} (3);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
It's not possible to increase the flow anymore,
|
||
because there is no path from the starting node
|
||
to the ending node with positive edge weights.
|
||
Thus, the algorithm terminates and the maximum flow is 7.
|
||
|
||
\subsubsection{Finding paths}
|
||
|
||
The Ford–Fulkerson algorithm doesn't specify
|
||
how the path that increases the flow should be chosen.
|
||
In any case, the algorithm will stop sooner or later
|
||
and produce a maximum flow.
|
||
However, the efficiency of the algorithm depends on
|
||
the way the paths are chosen.
|
||
|
||
A simple way to find paths is to use depth-first search.
|
||
Usually, this works well, but the worst case is that
|
||
each path only increases the flow by 1, and the algorithm becomes slow.
|
||
Fortunately, we can avoid this by using one of the following
|
||
algorithms:
|
||
|
||
\index{Edmonds–Karp algorithm}
|
||
|
||
The \key{Edmonds–Karp algorithm}
|
||
is an implementation of the
|
||
Ford–Fulkerson algorithm where
|
||
each path that increases the flow
|
||
is chosen so that the number of edges
|
||
in the path is minimum.
|
||
This can be done by using breadth-first search
|
||
instead of depth-first search.
|
||
It turns out that this guarantees that
|
||
flow increases quickly, and the time complexity
|
||
of the algorithm is $O(m^2 n)$.
|
||
|
||
\index{scaling algorithm}
|
||
|
||
The \key{scaling algorithm} uses depth-first
|
||
search to find paths where the weight of each edge is
|
||
at least a minimum value.
|
||
Initially, the minimum value is $c$,
|
||
the sum of capacities of the edges that
|
||
begin at the starting edge.
|
||
If the algorithm can't find a path,
|
||
the minimum value is divided by 2,
|
||
and finally it will be 1.
|
||
The time complexity of the algorithm is $O(m^2 \log c)$.
|
||
|
||
In practice, the scaling algorithm is easier to code
|
||
because we can use depth-first search to find paths.
|
||
Both algorithms are efficient enough for problems
|
||
that typically appear in programming contests.
|
||
|
||
\subsubsection{Minimum cut}
|
||
|
||
\index{minimum cut}
|
||
|
||
It turns out that once the Ford–Fulkerson algorithm
|
||
has found a maximum flow,
|
||
it has also produced a minimum cut.
|
||
Let $A$ be the set of nodes
|
||
that can be reached from the starting node
|
||
using positive edges.
|
||
In the example graph, $A$ contains nodes 1, 2 and 4:
|
||
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.9,label distance=-2mm]
|
||
\node[draw, circle,fill=lightgray] (1) at (1,1.3) {$1$};
|
||
\node[draw, circle,fill=lightgray] (2) at (3,2.6) {$2$};
|
||
\node[draw, circle] (3) at (5,2.6) {$3$};
|
||
\node[draw, circle] (4) at (7,1.3) {$6$};
|
||
\node[draw, circle,fill=lightgray] (5) at (3,0) {$4$};
|
||
\node[draw, circle] (6) at (5,0) {$5$};
|
||
|
||
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=2] {} (2);
|
||
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=below:3] {} (1);
|
||
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=0] {} (3);
|
||
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=below:6] {} (2);
|
||
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=0] {} (4);
|
||
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:5] {} (3);
|
||
\path[draw,thick,->] (1) edge [bend left=10] node[font=\small,label=0] {} (5);
|
||
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=below:4] {} (1);
|
||
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=0] {} (6);
|
||
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=below:1] {} (5);
|
||
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=0] {} (4);
|
||
\path[draw,thick,->] (4) edge [bend left=10] node[font=\small,label=below:2] {} (6);
|
||
\path[draw,thick,->] (5) edge [bend left=10] node[font=\small,label=left:0] {} (2);
|
||
\path[draw,thick,->] (2) edge [bend left=10] node[font=\small,label=right:3] {} (5);
|
||
\path[draw,thick,->] (3) edge [bend left=10] node[font=\small,label=right:7] {} (6);
|
||
\path[draw,thick,->] (6) edge [bend left=10] node[font=\small,label=left:1] {} (3);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
Now the minimum cut consists of the edges in the original graph
|
||
that begin at a node in $A$ and end at a node outside $A$,
|
||
and whose capacity is fully
|
||
used in the maximum flow.
|
||
In the above graph, such edges are
|
||
$2 \rightarrow 3$ and $4 \rightarrow 5$,
|
||
that correspond to the minimum cut $6+1=7$.
|
||
|
||
Why is the flow produced by the algorithm maximum,
|
||
and why is the cut minimum?
|
||
The reason for this is that a graph never
|
||
contains a flow whose size is larger
|
||
than the weight of any cut in the graph.
|
||
Hence, always when a flow and a cut are equally large,
|
||
they are a maximum flow and a minimum cut.
|
||
|
||
Let's consider any cut in the graph
|
||
where the starting node belongs to set $A$,
|
||
the ending node belongs to set $B$
|
||
and there are edges between the sets:
|
||
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.9]
|
||
\draw[dashed] (-2,0) circle (1.5);
|
||
\draw[dashed] (2,0) circle (1.5);
|
||
|
||
\node at (-2,-1) {$A$};
|
||
\node at (2,-1) {$B$};
|
||
|
||
\node[draw, circle] (1) at (-1,0.5) {};
|
||
\node[draw, circle] (2) at (-1,0) {};
|
||
\node[draw, circle] (3) at (-1,-0.5) {};
|
||
\node[draw, circle] (4) at (1,0.5) {};
|
||
\node[draw, circle] (5) at (1,0) {};
|
||
\node[draw, circle] (6) at (1,-0.5) {};
|
||
|
||
\path[draw,thick,->] (1) -- (4);
|
||
\path[draw,thick,->] (5) -- (2);
|
||
\path[draw,thick,->] (3) -- (6);
|
||
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
The weight of the cut is the sum of those edges
|
||
that go from set $A$ to set $B$.
|
||
This is an upper bound for the amount of flow
|
||
in the graph, because the flow has to proceed
|
||
from set $A$ to set $B$.
|
||
Thus, a maximum flow is smaller than or equal to
|
||
any cut in the graph.
|
||
|
||
On the other hand, the Ford–Fulkerson algorithm
|
||
produces a flow that is \emph{exactly} as large
|
||
as a cut in the graph.
|
||
Thus, the flow has to be a maximum flow,
|
||
and the cut has to be a minimum cut.
|
||
|
||
\section{Parallel paths}
|
||
|
||
As a first application for flows,
|
||
we consider a problem where the task is to
|
||
form as many parallel paths as possible
|
||
from the starting node of the graph
|
||
to the ending node.
|
||
It is required that no edge appears
|
||
in more than one path.
|
||
|
||
For example, in the graph
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.9]
|
||
\node[draw, circle] (1) at (1,2) {$1$};
|
||
\node[draw, circle] (2) at (3,3) {$2$};
|
||
\node[draw, circle] (3) at (5,3) {$3$};
|
||
\node[draw, circle] (4) at (3,1) {$4$};
|
||
\node[draw, circle] (5) at (5,1) {$5$};
|
||
\node[draw, circle] (6) at (7,2) {$6$};
|
||
\path[draw,thick,->] (1) -- (2);
|
||
\path[draw,thick,->] (1) -- (4);
|
||
\path[draw,thick,->] (2) -- (4);
|
||
\path[draw,thick,->] (3) -- (2);
|
||
\path[draw,thick,->] (3) -- (5);
|
||
\path[draw,thick,->] (3) -- (6);
|
||
\path[draw,thick,->] (4) -- (3);
|
||
\path[draw,thick,->] (4) -- (5);
|
||
\path[draw,thick,->] (5) -- (6);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
we can form two parallel paths from node 1 to node 6.
|
||
This can be done by choosing paths
|
||
$1 \rightarrow 2 \rightarrow 4 \rightarrow 3 \rightarrow 6$
|
||
and $1 \rightarrow 4 \rightarrow 5 \rightarrow 6$:
|
||
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.9]
|
||
\node[draw, circle] (1) at (1,2) {$1$};
|
||
\node[draw, circle] (2) at (3,3) {$2$};
|
||
\node[draw, circle] (3) at (5,3) {$3$};
|
||
\node[draw, circle] (4) at (3,1) {$4$};
|
||
\node[draw, circle] (5) at (5,1) {$5$};
|
||
\node[draw, circle] (6) at (7,2) {$6$};
|
||
\path[draw,thick,->] (1) -- (2);
|
||
\path[draw,thick,->] (1) -- (4);
|
||
\path[draw,thick,->] (2) -- (4);
|
||
\path[draw,thick,->] (3) -- (2);
|
||
\path[draw,thick,->] (3) -- (5);
|
||
\path[draw,thick,->] (3) -- (6);
|
||
\path[draw,thick,->] (4) -- (3);
|
||
\path[draw,thick,->] (4) -- (5);
|
||
\path[draw,thick,->] (5) -- (6);
|
||
|
||
\path[draw=green,thick,->,line width=2pt] (1) -- (2);
|
||
\path[draw=green,thick,->,line width=2pt] (2) -- (4);
|
||
\path[draw=green,thick,->,line width=2pt] (4) -- (3);
|
||
\path[draw=green,thick,->,line width=2pt] (3) -- (6);
|
||
|
||
\path[draw=blue,thick,->,line width=2pt] (1) -- (4);
|
||
\path[draw=blue,thick,->,line width=2pt] (4) -- (5);
|
||
\path[draw=blue,thick,->,line width=2pt] (5) -- (6);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
It turns out that the maximum number of parallel paths
|
||
equals the maximum flow in the graph when the weight
|
||
of each edge is 1.
|
||
After the maximum flow has been constructed,
|
||
the parallel paths can be found greedily by finding
|
||
paths from the starting node to the ending node.
|
||
|
||
Let's then consider a variation for the problem
|
||
where each node (except for the starting and ending nodes)
|
||
can appear in at most one path.
|
||
After this restriction, we can construct only one path
|
||
in the above graph, because node 4 can't appear
|
||
in more than one path:
|
||
|
||
\begin{center}
|
||
\begin{tikzpicture}
|
||
\node[draw, circle] (1) at (1,2) {$1$};
|
||
\node[draw, circle] (2) at (3,3) {$2$};
|
||
\node[draw, circle] (3) at (5,3) {$3$};
|
||
\node[draw, circle] (4) at (3,1) {$4$};
|
||
\node[draw, circle] (5) at (5,1) {$5$};
|
||
\node[draw, circle] (6) at (7,2) {$6$};
|
||
\path[draw,thick,->] (1) -- (2);
|
||
\path[draw,thick,->] (1) -- (4);
|
||
\path[draw,thick,->] (2) -- (4);
|
||
\path[draw,thick,->] (3) -- (2);
|
||
\path[draw,thick,->] (3) -- (5);
|
||
\path[draw,thick,->] (3) -- (6);
|
||
\path[draw,thick,->] (4) -- (3);
|
||
\path[draw,thick,->] (4) -- (5);
|
||
\path[draw,thick,->] (5) -- (6);
|
||
|
||
\path[draw=green,thick,->,line width=2pt] (1) -- (2);
|
||
\path[draw=green,thick,->,line width=2pt] (2) -- (4);
|
||
\path[draw=green,thick,->,line width=2pt] (4) -- (3);
|
||
\path[draw=green,thick,->,line width=2pt] (3) -- (6);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
A standard way to restrict the flow through a node
|
||
is to divide the node into two parts.
|
||
All incoming edges are connected to the first part,
|
||
and all outgoing edges are connected to the second part.
|
||
In addition, there is an edge from the first part
|
||
to the second part.
|
||
|
||
In the current example, the graph becomes as follows:
|
||
\begin{center}
|
||
\begin{tikzpicture}
|
||
\node[draw, circle] (1) at (1,2) {$1$};
|
||
|
||
\node[draw, circle] (2a) at (3,3) {$2$};
|
||
\node[draw, circle] (3a) at (6,3) {$3$};
|
||
\node[draw, circle] (4a) at (3,1) {$4$};
|
||
\node[draw, circle] (5a) at (6,1) {$5$};
|
||
|
||
\node[draw, circle] (2b) at (4,3) {$2$};
|
||
\node[draw, circle] (3b) at (7,3) {$3$};
|
||
\node[draw, circle] (4b) at (4,1) {$4$};
|
||
\node[draw, circle] (5b) at (7,1) {$5$};
|
||
|
||
\node[draw, circle] (6) at (9,2) {$6$};
|
||
|
||
\path[draw,thick,->] (2a) -- (2b);
|
||
\path[draw,thick,->] (3a) -- (3b);
|
||
\path[draw,thick,->] (4a) -- (4b);
|
||
\path[draw,thick,->] (5a) -- (5b);
|
||
|
||
\path[draw,thick,->] (1) -- (2a);
|
||
\path[draw,thick,->] (1) -- (4a);
|
||
\path[draw,thick,->] (2b) -- (4a);
|
||
\path[draw,thick,->] (3b) edge [bend right=30] (2a);
|
||
\path[draw,thick,->] (3b) -- (5a);
|
||
\path[draw,thick,->] (3b) -- (6);
|
||
\path[draw,thick,->] (4b) -- (3a);
|
||
\path[draw,thick,->] (4b) -- (5a);
|
||
\path[draw,thick,->] (5b) -- (6);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
The maximum flow for the graph is as follows:
|
||
\begin{center}
|
||
\begin{tikzpicture}
|
||
\node[draw, circle] (1) at (1,2) {$1$};
|
||
|
||
\node[draw, circle] (2a) at (3,3) {$2$};
|
||
\node[draw, circle] (3a) at (6,3) {$3$};
|
||
\node[draw, circle] (4a) at (3,1) {$4$};
|
||
\node[draw, circle] (5a) at (6,1) {$5$};
|
||
|
||
\node[draw, circle] (2b) at (4,3) {$2$};
|
||
\node[draw, circle] (3b) at (7,3) {$3$};
|
||
\node[draw, circle] (4b) at (4,1) {$4$};
|
||
\node[draw, circle] (5b) at (7,1) {$5$};
|
||
|
||
\node[draw, circle] (6) at (9,2) {$6$};
|
||
|
||
\path[draw,thick,->] (2a) -- (2b);
|
||
\path[draw,thick,->] (3a) -- (3b);
|
||
\path[draw,thick,->] (4a) -- (4b);
|
||
\path[draw,thick,->] (5a) -- (5b);
|
||
|
||
\path[draw,thick,->] (1) -- (2a);
|
||
\path[draw,thick,->] (1) -- (4a);
|
||
\path[draw,thick,->] (2b) -- (4a);
|
||
\path[draw,thick,->] (3b) edge [bend right=30] (2a);
|
||
\path[draw,thick,->] (3b) -- (5a);
|
||
\path[draw,thick,->] (3b) -- (6);
|
||
\path[draw,thick,->] (4b) -- (3a);
|
||
\path[draw,thick,->] (4b) -- (5a);
|
||
\path[draw,thick,->] (5b) -- (6);
|
||
|
||
\path[draw=red,thick,->,line width=2pt] (1) -- (2a);
|
||
\path[draw=red,thick,->,line width=2pt] (2a) -- (2b);
|
||
\path[draw=red,thick,->,line width=2pt] (2b) -- (4a);
|
||
\path[draw=red,thick,->,line width=2pt] (4a) -- (4b);
|
||
\path[draw=red,thick,->,line width=2pt] (4b) -- (3a);
|
||
\path[draw=red,thick,->,line width=2pt] (3a) -- (3b);
|
||
\path[draw=red,thick,->,line width=2pt] (3b) -- (6);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
This means that it is possible to form exactly
|
||
one path from the starting node to the ending node
|
||
when a node can't appear in more than one path.
|
||
|
||
\section{Maximum matching}
|
||
|
||
\index{matching}
|
||
\index{maximum matching}
|
||
|
||
A \key{maximum matching} is the largest possible
|
||
set of pairs of nodes in a graph
|
||
such that there is an edge between each pair of nodes,
|
||
and each node belongs to at most one pair.
|
||
|
||
There is a polynomial algorithm for finding
|
||
a maximum matching in a general graph,
|
||
but it is very complex.
|
||
For this reason, we will restrict ourselves to the
|
||
case where the graph is bipartite.
|
||
In this case we can easily find the maximum matching
|
||
using a maximum flow algorithm.
|
||
|
||
\subsubsection{Finding a maximum matching}
|
||
|
||
A bipartite graph can be always presented so
|
||
that it consists of left-side and right-side nodes,
|
||
and all edges in the graph go between
|
||
left and right sides.
|
||
As an example, consider the following graph:
|
||
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.60]
|
||
\node[draw, circle] (1) at (2,4.5) {1};
|
||
\node[draw, circle] (2) at (2,3) {2};
|
||
\node[draw, circle] (3) at (2,1.5) {3};
|
||
\node[draw, circle] (4) at (2,0) {4};
|
||
\node[draw, circle] (5) at (8,4.5) {5};
|
||
\node[draw, circle] (6) at (8,3) {6};
|
||
\node[draw, circle] (7) at (8,1.5) {7};
|
||
\node[draw, circle] (8) at (8,0) {8};
|
||
|
||
\path[draw,thick,-] (1) -- (5);
|
||
\path[draw,thick,-] (2) -- (7);
|
||
\path[draw,thick,-] (3) -- (5);
|
||
\path[draw,thick,-] (3) -- (6);
|
||
\path[draw,thick,-] (3) -- (8);
|
||
\path[draw,thick,-] (4) -- (7);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
In this graph, the size of a maximum matching is 3:
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.60]
|
||
\node[draw, circle] (1) at (2,4.5) {1};
|
||
\node[draw, circle] (2) at (2,3) {2};
|
||
\node[draw, circle] (3) at (2,1.5) {3};
|
||
\node[draw, circle] (4) at (2,0) {4};
|
||
\node[draw, circle] (5) at (8,4.5) {5};
|
||
\node[draw, circle] (6) at (8,3) {6};
|
||
\node[draw, circle] (7) at (8,1.5) {7};
|
||
\node[draw, circle] (8) at (8,0) {8};
|
||
|
||
\path[draw,thick,-] (1) -- (5);
|
||
\path[draw,thick,-] (2) -- (7);
|
||
\path[draw,thick,-] (3) -- (5);
|
||
\path[draw,thick,-] (3) -- (6);
|
||
\path[draw,thick,-] (3) -- (8);
|
||
\path[draw,thick,-] (4) -- (7);
|
||
|
||
\path[draw=red,thick,-,line width=2pt] (1) -- (5);
|
||
\path[draw=red,thick,-,line width=2pt] (2) -- (7);
|
||
\path[draw=red,thick,-,line width=2pt] (3) -- (6);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
A maximum matching in a bipartite graph
|
||
corresponds to a maximum flow in an extended graph
|
||
that contains a starting node,
|
||
an ending node and all the nodes of the original graph.
|
||
There is an edge from the starting node to
|
||
each left-side node, and an edge from
|
||
each right-side node to the ending node.
|
||
The capacity of each edge is 1.
|
||
|
||
In the example graph, the result is as follows:
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.60]
|
||
\node[draw, circle] (1) at (2,4.5) {1};
|
||
\node[draw, circle] (2) at (2,3) {2};
|
||
\node[draw, circle] (3) at (2,1.5) {3};
|
||
\node[draw, circle] (4) at (2,0) {4};
|
||
\node[draw, circle] (5) at (8,4.5) {5};
|
||
\node[draw, circle] (6) at (8,3) {6};
|
||
\node[draw, circle] (7) at (8,1.5) {7};
|
||
\node[draw, circle] (8) at (8,0) {8};
|
||
|
||
\node[draw, circle] (a) at (-2,2.25) {\phantom{0}};
|
||
\node[draw, circle] (b) at (12,2.25) {\phantom{0}};
|
||
|
||
\path[draw,thick,->] (1) -- (5);
|
||
\path[draw,thick,->] (2) -- (7);
|
||
\path[draw,thick,->] (3) -- (5);
|
||
\path[draw,thick,->] (3) -- (6);
|
||
\path[draw,thick,->] (3) -- (8);
|
||
\path[draw,thick,->] (4) -- (7);
|
||
|
||
\path[draw,thick,->] (a) -- (1);
|
||
\path[draw,thick,->] (a) -- (2);
|
||
\path[draw,thick,->] (a) -- (3);
|
||
\path[draw,thick,->] (a) -- (4);
|
||
\path[draw,thick,->] (5) -- (b);
|
||
\path[draw,thick,->] (6) -- (b);
|
||
\path[draw,thick,->] (7) -- (b);
|
||
\path[draw,thick,->] (8) -- (b);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
The size of a maximum flow in this graph
|
||
equals the size of a maximum matching
|
||
in the original graph,
|
||
because each path from the starting node
|
||
to the ending node adds one edge to the matching.
|
||
In this graph, the maximum flow is 3,
|
||
so the maximum matching is also 3.
|
||
|
||
\subsubsection{Hall's theorem}
|
||
|
||
\index{Hall's theorem}
|
||
\index{perfect matching}
|
||
|
||
\key{Hall's theorem} describes when a bipartite graph
|
||
has a matching that contains all nodes
|
||
in one side of the graph.
|
||
If both sides contain the same number of nodes,
|
||
Hall's theorem tells us if it's possible to
|
||
construct a \key{perfect matching} where
|
||
all nodes are paired with each other.
|
||
|
||
Assume that we want to construct a matching
|
||
that contains all left-side nodes.
|
||
Let $X$ be a set of left-side nodes,
|
||
and let $f(X)$ be the set of their neighbors.
|
||
According to Hall's theorem, a such matching exists
|
||
exactly when for each $X$, the condition $|X| \le |f(X)|$ holds.
|
||
|
||
Let's study Hall's theorem in the example graph.
|
||
First, let $X=\{1,3\}$ and $f(X)=\{5,6,8\}$:
|
||
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.60]
|
||
\node[draw, circle, fill=lightgray] (1) at (2,4.5) {1};
|
||
\node[draw, circle] (2) at (2,3) {2};
|
||
\node[draw, circle, fill=lightgray] (3) at (2,1.5) {3};
|
||
\node[draw, circle] (4) at (2,0) {4};
|
||
\node[draw, circle, fill=lightgray] (5) at (8,4.5) {5};
|
||
\node[draw, circle, fill=lightgray] (6) at (8,3) {6};
|
||
\node[draw, circle] (7) at (8,1.5) {7};
|
||
\node[draw, circle, fill=lightgray] (8) at (8,0) {8};
|
||
|
||
\path[draw,thick,-] (1) -- (5);
|
||
\path[draw,thick,-] (2) -- (7);
|
||
\path[draw,thick,-] (3) -- (5);
|
||
\path[draw,thick,-] (3) -- (6);
|
||
\path[draw,thick,-] (3) -- (8);
|
||
\path[draw,thick,-] (4) -- (7);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
The condition of Hall's theorem holds, because
|
||
$|X|=2$ and $|f(X)|=3$.
|
||
Next, let $X=\{2,4\}$ and $f(X)=\{7\}$:
|
||
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.60]
|
||
\node[draw, circle] (1) at (2,4.5) {1};
|
||
\node[draw, circle, fill=lightgray] (2) at (2,3) {2};
|
||
\node[draw, circle] (3) at (2,1.5) {3};
|
||
\node[draw, circle, fill=lightgray] (4) at (2,0) {4};
|
||
\node[draw, circle] (5) at (8,4.5) {5};
|
||
\node[draw, circle] (6) at (8,3) {6};
|
||
\node[draw, circle, fill=lightgray] (7) at (8,1.5) {7};
|
||
\node[draw, circle] (8) at (8,0) {8};
|
||
|
||
\path[draw,thick,-] (1) -- (5);
|
||
\path[draw,thick,-] (2) -- (7);
|
||
\path[draw,thick,-] (3) -- (5);
|
||
\path[draw,thick,-] (3) -- (6);
|
||
\path[draw,thick,-] (3) -- (8);
|
||
\path[draw,thick,-] (4) -- (7);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
In this case, $|X|=2$ and $|f(X)|=1$,
|
||
so the condition of Hall's theorem doesn't hold.
|
||
This means that it's not possible to form
|
||
a perfect matching in the graph.
|
||
This result is not surprising, because we already
|
||
knew that the maximum matching in the graph is 3 and not 4.
|
||
|
||
If the condition of Hall's theorem doesn't hold,
|
||
the set $X$ provides an explanation why we can't form a matching.
|
||
Since $X$ contains more nodes than $f(X)$,
|
||
there is no pair for all nodes in $X$.
|
||
For example, in the above graph, both nodes 2 and 4
|
||
should be connected to node 7 which is not possible.
|
||
|
||
\subsubsection{Kőnig's theorem}
|
||
|
||
\index{Kőnig's theorem}
|
||
\index{node cover}
|
||
\index{minimum node cover}
|
||
|
||
\key{Kőnig's theorem} provides an efficient way
|
||
to construct a \key{minimum node cover} for a
|
||
bipartite graph.
|
||
This is a minimum set of nodes such that
|
||
each edge in the graph is connected to at least
|
||
one node in the set.
|
||
|
||
In a general graph, finding a minimum node cover
|
||
is a NP-hard problem.
|
||
However, in a bipartite graph,
|
||
the size of
|
||
a maximum matching and a minimum node cover
|
||
is always the same, according to Kőnig's theorem.
|
||
Thus, we can efficiently find a minimum node cover
|
||
using a maximum flow algorithm.
|
||
|
||
Let's consider the following graph
|
||
with a maximum matching of size 3:
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.60]
|
||
\node[draw, circle] (1) at (2,4.5) {1};
|
||
\node[draw, circle] (2) at (2,3) {2};
|
||
\node[draw, circle] (3) at (2,1.5) {3};
|
||
\node[draw, circle] (4) at (2,0) {4};
|
||
\node[draw, circle] (5) at (8,4.5) {5};
|
||
\node[draw, circle] (6) at (8,3) {6};
|
||
\node[draw, circle] (7) at (8,1.5) {7};
|
||
\node[draw, circle] (8) at (8,0) {8};
|
||
|
||
\path[draw,thick,-] (1) -- (5);
|
||
\path[draw,thick,-] (2) -- (7);
|
||
\path[draw,thick,-] (3) -- (5);
|
||
\path[draw,thick,-] (3) -- (6);
|
||
\path[draw,thick,-] (3) -- (8);
|
||
\path[draw,thick,-] (4) -- (7);
|
||
|
||
\path[draw=red,thick,-,line width=2pt] (1) -- (5);
|
||
\path[draw=red,thick,-,line width=2pt] (2) -- (7);
|
||
\path[draw=red,thick,-,line width=2pt] (3) -- (6);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
Using Kőnig's theorem, we know that the size
|
||
of a minimum node cover is also 3.
|
||
It can be constructed as follows:
|
||
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.60]
|
||
\node[draw, circle, fill=lightgray] (1) at (2,4.5) {1};
|
||
\node[draw, circle] (2) at (2,3) {2};
|
||
\node[draw, circle, fill=lightgray] (3) at (2,1.5) {3};
|
||
\node[draw, circle] (4) at (2,0) {4};
|
||
\node[draw, circle] (5) at (8,4.5) {5};
|
||
\node[draw, circle] (6) at (8,3) {6};
|
||
\node[draw, circle, fill=lightgray] (7) at (8,1.5) {7};
|
||
\node[draw, circle] (8) at (8,0) {8};
|
||
|
||
\path[draw,thick,-] (1) -- (5);
|
||
\path[draw,thick,-] (2) -- (7);
|
||
\path[draw,thick,-] (3) -- (5);
|
||
\path[draw,thick,-] (3) -- (6);
|
||
\path[draw,thick,-] (3) -- (8);
|
||
\path[draw,thick,-] (4) -- (7);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
For each edge in the maximum matching,
|
||
exactly one of its end nodes belongs to
|
||
the minimum node cover.
|
||
|
||
\index{independent set}
|
||
\index{maximum independent set}
|
||
|
||
The set of all nodes that do \emph{not}
|
||
belong to a minimum node cover
|
||
forms a \key{maximum independent set}.
|
||
This is the largest possible set of nodes
|
||
where there is no edge between any two nodes
|
||
in the graph.
|
||
Once again, finding a maximum independent
|
||
set in a general graph is a NP-hard problem,
|
||
but in a bipartite graph we can use
|
||
Kőnig's theorem to solve the problem efficiently.
|
||
In the example graph, the maximum independent
|
||
set is as follows:
|
||
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.60]
|
||
\node[draw, circle] (1) at (2,4.5) {1};
|
||
\node[draw, circle, fill=lightgray] (2) at (2,3) {2};
|
||
\node[draw, circle] (3) at (2,1.5) {3};
|
||
\node[draw, circle, fill=lightgray] (4) at (2,0) {4};
|
||
\node[draw, circle, fill=lightgray] (5) at (8,4.5) {5};
|
||
\node[draw, circle, fill=lightgray] (6) at (8,3) {6};
|
||
\node[draw, circle] (7) at (8,1.5) {7};
|
||
\node[draw, circle, fill=lightgray] (8) at (8,0) {8};
|
||
|
||
\path[draw,thick,-] (1) -- (5);
|
||
\path[draw,thick,-] (2) -- (7);
|
||
\path[draw,thick,-] (3) -- (5);
|
||
\path[draw,thick,-] (3) -- (6);
|
||
\path[draw,thick,-] (3) -- (8);
|
||
\path[draw,thick,-] (4) -- (7);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
\section{Path covers}
|
||
|
||
\index{path cover}
|
||
|
||
A \key{path cover} is a set of paths in a graph
|
||
that is chosen so that each node in the graph
|
||
belongs to at least one path.
|
||
It turns out that we can reduce the problem
|
||
of finding a minimum path cover in a
|
||
directed, acyclic graph into a maximum flow problem.
|
||
|
||
There are two variations for the problem:
|
||
In a \key{node-disjoint cover},
|
||
every node appears in exactly one path,
|
||
and in a \key{general cover},
|
||
a node may appear in more than one path.
|
||
In both cases, the minimum path cover can be
|
||
found using a similar idea.
|
||
|
||
\subsubsection{Node-disjoint cover}
|
||
|
||
As an example, consider the following graph:
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.9]
|
||
\node[draw, circle] (1) at (0,0) {1};
|
||
\node[draw, circle] (2) at (2,0) {2};
|
||
\node[draw, circle] (3) at (4,0) {3};
|
||
\node[draw, circle] (4) at (6,0) {4};
|
||
\node[draw, circle] (5) at (0,-2) {5};
|
||
\node[draw, circle] (6) at (2,-2) {6};
|
||
\node[draw, circle] (7) at (4,-2) {7};
|
||
|
||
\path[draw,thick,->,>=latex] (1) -- (5);
|
||
\path[draw,thick,->,>=latex] (2) -- (6);
|
||
\path[draw,thick,->,>=latex] (3) -- (4);
|
||
\path[draw,thick,->,>=latex] (5) -- (6);
|
||
\path[draw,thick,->,>=latex] (6) -- (3);
|
||
\path[draw,thick,->,>=latex] (6) -- (7);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
In this case, the minimum node-disjoint path cover
|
||
consists of three paths.
|
||
For example, we can choose the following paths:
|
||
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.9]
|
||
\node[draw, circle] (1) at (0,0) {1};
|
||
\node[draw, circle] (2) at (2,0) {2};
|
||
\node[draw, circle] (3) at (4,0) {3};
|
||
\node[draw, circle] (4) at (6,0) {4};
|
||
\node[draw, circle] (5) at (0,-2) {5};
|
||
\node[draw, circle] (6) at (2,-2) {6};
|
||
\node[draw, circle] (7) at (4,-2) {7};
|
||
|
||
\path[draw=red,thick,->,line width=2pt] (1) -- (5);
|
||
\path[draw=red,thick,->,line width=2pt] (5) -- (6);
|
||
\path[draw=red,thick,->,line width=2pt] (6) -- (7);
|
||
\path[draw=red,thick,->,line width=2pt] (3) -- (4);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
Note that one of the paths only contains node 2,
|
||
so it is possible that a path doesn't contain any edges.
|
||
|
||
Finding a path cover can be interpreted as finding
|
||
a maximum matching in a graph where each node
|
||
in the original graph is represented by two nodes:
|
||
a left node and a right node.
|
||
There is an edge from a left node to a right node,
|
||
if there is such an edge in the original graph.
|
||
The idea is that the matching determines which
|
||
edges belong to paths in the original graph.
|
||
|
||
The matching in the example case is as follows:
|
||
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.9]
|
||
\node[draw, circle] (1a) at (0,6) {1};
|
||
\node[draw, circle] (2a) at (0,5) {2};
|
||
\node[draw, circle] (3a) at (0,4) {3};
|
||
\node[draw, circle] (4a) at (0,3) {4};
|
||
\node[draw, circle] (5a) at (0,2) {5};
|
||
\node[draw, circle] (6a) at (0,1) {6};
|
||
\node[draw, circle] (7a) at (0,0) {7};
|
||
|
||
\node[draw, circle] (1b) at (4,6) {1};
|
||
\node[draw, circle] (2b) at (4,5) {2};
|
||
\node[draw, circle] (3b) at (4,4) {3};
|
||
\node[draw, circle] (4b) at (4,3) {4};
|
||
\node[draw, circle] (5b) at (4,2) {5};
|
||
\node[draw, circle] (6b) at (4,1) {6};
|
||
\node[draw, circle] (7b) at (4,0) {7};
|
||
|
||
\node[draw, circle] (a) at (-3,3) {\phantom{0}};
|
||
\node[draw, circle] (b) at (7,3) {\phantom{0}};
|
||
|
||
%\path[draw,thick,->,>=latex] (1a) -- (5b);
|
||
\path[draw,thick,->,>=latex] (2a) -- (6b);
|
||
%\path[draw,thick,->,>=latex] (3a) -- (4b);
|
||
%\path[draw,thick,->,>=latex] (5a) -- (6b);
|
||
\path[draw,thick,->,>=latex] (6a) -- (3b);
|
||
%\path[draw,thick,->,>=latex] (6a) -- (7b);
|
||
|
||
\path[draw,thick,->,>=latex] (a) -- (1a);
|
||
\path[draw,thick,->,>=latex] (a) -- (2a);
|
||
\path[draw,thick,->,>=latex] (a) -- (3a);
|
||
\path[draw,thick,->,>=latex] (a) -- (4a);
|
||
\path[draw,thick,->,>=latex] (a) -- (5a);
|
||
\path[draw,thick,->,>=latex] (a) -- (6a);
|
||
\path[draw,thick,->,>=latex] (a) -- (7a);
|
||
|
||
\path[draw,thick,->,>=latex] (1b) -- (b);
|
||
\path[draw,thick,->,>=latex] (2b) -- (b);
|
||
\path[draw,thick,->,>=latex] (3b) -- (b);
|
||
\path[draw,thick,->,>=latex] (4b) -- (b);
|
||
\path[draw,thick,->,>=latex] (5b) -- (b);
|
||
\path[draw,thick,->,>=latex] (6b) -- (b);
|
||
\path[draw,thick,->,>=latex] (7b) -- (b);
|
||
|
||
\path[draw=red,thick,->,line width=2pt] (1a) -- (5b);
|
||
\path[draw=red,thick,->,line width=2pt] (5a) -- (6b);
|
||
\path[draw=red,thick,->,line width=2pt] (6a) -- (7b);
|
||
\path[draw=red,thick,->,line width=2pt] (3a) -- (4b);
|
||
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
In this case, the maximum matching consists of four edges
|
||
that corresponds to edges
|
||
$1 \rightarrow 5$, $3 \rightarrow 4$,
|
||
$5 \rightarrow 6$ and $6 \rightarrow 7$ in the original graph.
|
||
Thus, a minimum node-disjoint path cover consists of paths
|
||
that contain these edges.
|
||
|
||
The size of a minimum path cover is $n-c$ where
|
||
$n$ is the number of nodes in the graph,
|
||
and $c$ is the number of edges in the maximum matching.
|
||
For example, in the above graph the size of the
|
||
minimum path cover is $7-4=3$.
|
||
|
||
\subsubsection{General cover}
|
||
|
||
In a general path cover, a node can belong to more than one path
|
||
which may decrease the number of paths needed.
|
||
In the example graph, the minimum general path cover
|
||
consists of two paths as follows:
|
||
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.9]
|
||
\node[draw, circle] (1) at (0,0) {1};
|
||
\node[draw, circle] (2) at (2,0) {2};
|
||
\node[draw, circle] (3) at (4,0) {3};
|
||
\node[draw, circle] (4) at (6,0) {4};
|
||
\node[draw, circle] (5) at (0,-2) {5};
|
||
\node[draw, circle] (6) at (2,-2) {6};
|
||
\node[draw, circle] (7) at (4,-2) {7};
|
||
|
||
\path[draw=blue,thick,->,line width=2pt] (1) -- (5);
|
||
\path[draw=blue,thick,->,line width=2pt] (5) -- (6);
|
||
\path[draw=blue,thick,->,line width=2pt] (6) -- (3);
|
||
\path[draw=blue,thick,->,line width=2pt] (3) -- (4);
|
||
\path[draw=green,thick,->,line width=2pt] (2) -- (6);
|
||
\path[draw=green,thick,->,line width=2pt] (6) -- (7);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
In this graph, a minimum general path cover contains 2 paths,
|
||
while a minimum node-disjoint path cover contains 3 paths.
|
||
The difference is that in the general path cover,
|
||
node 6 appears in two paths.
|
||
|
||
A minimum general path cover can be found
|
||
almost like a minimum node-disjoint path cover.
|
||
It suffices to extend the matching graph
|
||
so that there is an edge $a \rightarrow b$
|
||
always when there is a path from node $a$ to node $b$
|
||
in the original graph (possibly through several edges).
|
||
|
||
The matching graph for the example case looks as follows:
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.9]
|
||
\node[draw, circle] (1a) at (0,6) {1};
|
||
\node[draw, circle] (2a) at (0,5) {2};
|
||
\node[draw, circle] (3a) at (0,4) {3};
|
||
\node[draw, circle] (4a) at (0,3) {4};
|
||
\node[draw, circle] (5a) at (0,2) {5};
|
||
\node[draw, circle] (6a) at (0,1) {6};
|
||
\node[draw, circle] (7a) at (0,0) {7};
|
||
|
||
\node[draw, circle] (1b) at (4,6) {1};
|
||
\node[draw, circle] (2b) at (4,5) {2};
|
||
\node[draw, circle] (3b) at (4,4) {3};
|
||
\node[draw, circle] (4b) at (4,3) {4};
|
||
\node[draw, circle] (5b) at (4,2) {5};
|
||
\node[draw, circle] (6b) at (4,1) {6};
|
||
\node[draw, circle] (7b) at (4,0) {7};
|
||
|
||
\node[draw, circle] (a) at (-3,3) {\phantom{0}};
|
||
\node[draw, circle] (b) at (7,3) {\phantom{0}};
|
||
|
||
|
||
%\path[draw,thick,->,>=latex] (1a) -- (5b);
|
||
\path[draw,thick,->,>=latex] (1a) -- (6b);
|
||
\path[draw,thick,->,>=latex] (1a) -- (7b);
|
||
\path[draw,thick,->,>=latex] (1a) -- (3b);
|
||
\path[draw,thick,->,>=latex] (1a) -- (4b);
|
||
\path[draw,thick,->,>=latex] (5a) -- (6b);
|
||
\path[draw,thick,->,>=latex] (5a) -- (7b);
|
||
%\path[draw,thick,->,>=latex] (5a) -- (3b);
|
||
\path[draw,thick,->,>=latex] (5a) -- (4b);
|
||
\path[draw,thick,->,>=latex] (6a) -- (7b);
|
||
%\path[draw,thick,->,>=latex] (6a) -- (7b);
|
||
\path[draw,thick,->,>=latex] (6a) -- (3b);
|
||
%\path[draw,thick,->,>=latex] (3a) -- (4b);
|
||
%\path[draw,thick,->,>=latex] (2a) -- (6b);
|
||
\path[draw,thick,->,>=latex] (2a) -- (7b);
|
||
\path[draw,thick,->,>=latex] (2a) -- (3b);
|
||
\path[draw,thick,->,>=latex] (2a) -- (4b);
|
||
|
||
|
||
\path[draw,thick,->,>=latex] (a) -- (1a);
|
||
\path[draw,thick,->,>=latex] (a) -- (2a);
|
||
\path[draw,thick,->,>=latex] (a) -- (3a);
|
||
\path[draw,thick,->,>=latex] (a) -- (4a);
|
||
\path[draw,thick,->,>=latex] (a) -- (5a);
|
||
\path[draw,thick,->,>=latex] (a) -- (6a);
|
||
\path[draw,thick,->,>=latex] (a) -- (7a);
|
||
|
||
\path[draw,thick,->,>=latex] (1b) -- (b);
|
||
\path[draw,thick,->,>=latex] (2b) -- (b);
|
||
\path[draw,thick,->,>=latex] (3b) -- (b);
|
||
\path[draw,thick,->,>=latex] (4b) -- (b);
|
||
\path[draw,thick,->,>=latex] (5b) -- (b);
|
||
\path[draw,thick,->,>=latex] (6b) -- (b);
|
||
\path[draw,thick,->,>=latex] (7b) -- (b);
|
||
|
||
\path[draw=red,thick,->,line width=2pt] (1a) -- (5b);
|
||
\path[draw=red,thick,->,line width=2pt] (5a) -- (3b);
|
||
\path[draw=red,thick,->,line width=2pt] (3a) -- (4b);
|
||
\path[draw=red,thick,->,line width=2pt] (2a) -- (6b);
|
||
\path[draw=red,thick,->,line width=2pt] (6a) -- (7b);
|
||
|
||
|
||
% \path[draw=red,thick,->,line width=2pt] (1a) -- (6b);
|
||
% \path[draw=red,thick,->,line width=2pt] (1a) -- (7b);
|
||
% \path[draw=red,thick,->,line width=2pt] (1a) -- (3b);
|
||
% \path[draw=red,thick,->,line width=2pt] (1a) -- (4b);
|
||
% \path[draw=red,thick,->,line width=2pt] (5a) -- (6b);
|
||
% \path[draw=red,thick,->,line width=2pt] (5a) -- (7b);
|
||
% \path[draw=red,thick,->,line width=2pt] (5a) -- (3b);
|
||
% \path[draw=red,thick,->,line width=2pt] (5a) -- (4b);
|
||
% \path[draw=red,thick,->,line width=2pt] (6a) -- (7b);
|
||
% \path[draw=red,thick,->,line width=2pt] (6a) -- (7b);
|
||
% \path[draw=red,thick,->,line width=2pt] (6a) -- (3b);
|
||
% \path[draw=red,thick,->,line width=2pt] (3a) -- (4b);
|
||
% \path[draw=red,thick,->,line width=2pt] (2a) -- (6b);
|
||
% \path[draw=red,thick,->,line width=2pt] (2a) -- (7b);
|
||
% \path[draw=red,thick,->,line width=2pt] (2a) -- (3b);
|
||
% \path[draw=red,thick,->,line width=2pt] (2a) -- (4b);
|
||
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
\subsubsection{Dilworth's theorem}
|
||
|
||
\index{Dilworth's theorem}
|
||
\index{antichain}
|
||
|
||
\key{Dilworth's theorem} states that the size of
|
||
a minimum general path cover in a directed, acyclic graph
|
||
equals the maximum size of an \key{antichain}, i.e.,
|
||
a set of nodes such that there is no path
|
||
from any node to another node.
|
||
|
||
For example, in the example graph, the minimum
|
||
general path cover contains two paths,
|
||
so the largest antichain contains two nodes.
|
||
We can construct such an antichain
|
||
by choosing nodes 3 and 7:
|
||
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=0.9]
|
||
\node[draw, circle] (1) at (0,0) {1};
|
||
\node[draw, circle] (2) at (2,0) {2};
|
||
\node[draw, circle, fill=lightgray] (3) at (4,0) {3};
|
||
\node[draw, circle] (4) at (6,0) {4};
|
||
\node[draw, circle] (5) at (0,-2) {5};
|
||
\node[draw, circle] (6) at (2,-2) {6};
|
||
\node[draw, circle, fill=lightgray] (7) at (4,-2) {7};
|
||
|
||
\path[draw,thick,->,>=latex] (1) -- (5);
|
||
\path[draw,thick,->,>=latex] (2) -- (6);
|
||
\path[draw,thick,->,>=latex] (3) -- (4);
|
||
\path[draw,thick,->,>=latex] (5) -- (6);
|
||
\path[draw,thick,->,>=latex] (6) -- (3);
|
||
\path[draw,thick,->,>=latex] (6) -- (7);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
|
||
There is no path from node 3 to node 7,
|
||
and no path from node 7 to node 3,
|
||
so nodes 3 and 7 form an antichain.
|
||
On the other hand, if we choose any three
|
||
nodes in the graph, there is certainly a
|
||
path from one node to another node.
|