cphb/luku20.tex

1366 lines
50 KiB
TeX
Raw Normal View History

2017-01-10 21:33:14 +01:00
\chapter{Flows and cuts}
2016-12-28 23:54:51 +01:00
2017-01-10 21:33:14 +01:00
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:
2016-12-28 23:54:51 +01:00
\begin{itemize}
2017-01-10 21:33:14 +01:00
\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?
2016-12-28 23:54:51 +01:00
\end{itemize}
2017-01-10 21:33:14 +01:00
It turns out that these problems correspond to
each other, and we can solve them simultaneously
using the same algorithm.
2016-12-28 23:54:51 +01:00
2017-01-10 21:33:14 +01:00
As an example, we will use the following graph
where node 1 is the starting node and node 6
is the ending node:
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 21:33:14 +01:00
\subsubsection{Maximum flow}
2016-12-28 23:54:51 +01:00
2017-01-10 21:33:14 +01:00
\index{flow}
\index{maximum flow}
2016-12-28 23:54:51 +01:00
2017-01-10 21:33:14 +01:00
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.
2016-12-28 23:54:51 +01:00
2017-01-10 21:33:14 +01:00
A maximum flow for the example graph
is as follows:
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 21:33:14 +01:00
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$.
2016-12-28 23:54:51 +01:00
2017-01-10 21:33:14 +01:00
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.
2016-12-28 23:54:51 +01:00
2017-01-10 21:33:14 +01:00
\subsubsection{Minimum cut}
2016-12-28 23:54:51 +01:00
2017-01-10 21:33:14 +01:00
\index{cut}
\index{minimum cut}
2016-12-28 23:54:51 +01:00
2017-01-10 21:33:14 +01:00
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.
2016-12-28 23:54:51 +01:00
2017-01-10 21:33:14 +01:00
A minimum cut for the example graph is as follows:
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 21:33:14 +01:00
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$.
2016-12-28 23:54:51 +01:00
\\\\
2017-01-10 21:33:14 +01:00
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 FordFulkerson
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{FordFulkerson algorithm}
\index{FordFulkerson algorithm}
The \key{FordFulkerson 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.
2016-12-28 23:54:51 +01:00
\begin{samepage}
2017-01-10 21:33:14 +01:00
The new representation for the example graph is as follows:
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 21:33:14 +01:00
The FordFulkerson 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.
2016-12-28 23:54:51 +01:00
2017-01-10 21:33:14 +01:00
In the example graph, we can choose, say, the following path:
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 21:33:14 +01:00
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$.
2016-12-28 23:54:51 +01:00
2017-01-10 21:33:14 +01:00
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:
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 21:33:14 +01:00
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.
2016-12-28 23:54:51 +01:00
2017-01-10 21:33:14 +01:00
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:
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 21:33:14 +01:00
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.
2016-12-28 23:54:51 +01:00
\begin{samepage}
2017-01-10 21:33:14 +01:00
The new graph will be as follows:
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 21:33:14 +01:00
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:
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 21:33:14 +01:00
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 FordFulkerson 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{EdmondsKarp algorithm}
The \key{EdmondsKarp algorithm}
is an implementation of the
FordFulkerson 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 FordFulkerson 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:
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 21:33:14 +01:00
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:
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 21:33:14 +01:00
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 FordFulkerson 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.
2016-12-28 23:54:51 +01:00
2017-01-10 22:34:36 +01:00
\section{Parallel paths}
2016-12-28 23:54:51 +01:00
2017-01-10 22:34:36 +01:00
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.
2016-12-28 23:54:51 +01:00
2017-01-10 22:34:36 +01:00
For example, in the graph
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 22:34:36 +01:00
we can form two parallel paths from node 1 to node 6.
This can be done by choosing paths
2016-12-28 23:54:51 +01:00
$1 \rightarrow 2 \rightarrow 4 \rightarrow 3 \rightarrow 6$
2017-01-10 22:34:36 +01:00
and $1 \rightarrow 4 \rightarrow 5 \rightarrow 6$:
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 22:34:36 +01:00
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:
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 22:34:36 +01:00
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.
2016-12-28 23:54:51 +01:00
2017-01-10 22:34:36 +01:00
In the current example, the graph becomes as follows:
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 22:34:36 +01:00
The maximum flow for the graph is as follows:
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 22:34:36 +01:00
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.
2016-12-28 23:54:51 +01:00
2017-01-10 22:34:36 +01:00
\section{Maximum matching}
2016-12-28 23:54:51 +01:00
2017-01-10 22:34:36 +01:00
\index{matching}
\index{maximum matching}
2016-12-28 23:54:51 +01:00
2017-01-10 22:34:36 +01:00
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.
2016-12-28 23:54:51 +01:00
2017-01-10 22:34:36 +01:00
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.
2016-12-28 23:54:51 +01:00
2017-01-10 22:34:36 +01:00
\subsubsection{Finding a maximum matching}
2016-12-28 23:54:51 +01:00
2017-01-10 22:34:36 +01:00
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:
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 22:34:36 +01:00
In this graph, the size of a maximum matching is 3:
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 22:34:36 +01:00
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.
2016-12-28 23:54:51 +01:00
2017-01-10 22:34:36 +01:00
In the example graph, the result is as follows:
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 22:34:36 +01:00
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\}$:
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 22:34:36 +01:00
The condition of Hall's theorem holds, because
$|X|=2$ and $|f(X)|=3$.
Next, let $X=\{2,4\}$ and $f(X)=\{7\}$:
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 22:34:36 +01:00
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:
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 22:34:36 +01:00
Using Kőnig's theorem, we know that the size
of a minimum node cover is also 3.
It can be constructed as follows:
2016-12-28 23:54:51 +01:00
\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}
2017-01-10 22:34:36 +01:00
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
is 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:
2016-12-28 23:54:51 +01:00
\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{Polkupeitteet}
\index{polkupeite@polkupeite}
\key{Polkupeite} on joukko verkon polkuja,
jotka on valittu niin, että jokainen verkon solmu kuuluu
ainakin yhteen polkuun.
Osoittautuu, että voimme muodostaa
virtauslaskennan avulla
pienimmän polkupeitteen suunnatussa,
syklittömässä verkossa.
Polkupeitteestä on kaksi muunnelmaa:
\key{Solmuerillinen peite} on polkupeite,
jossa jokainen verkon solmu esiintyy tasan yhdessä polussa.
\key{Yleinen peite} taas on polkupeite, jossa sama solmu voi
esiintyä useammassa polussa.
Kummassakin tapauksessa pienin polkupeite löytyy
samanlaisella idealla.
\subsubsection{Solmuerillinen peite}
Tarkastellaan esimerkkinä seuraavaa verkkoa:
\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}
Tässä tapauksessa pienin solmuerillinen polkupeite
muodostuu kolmesta polusta.
Voimme valita polut esimerkiksi seuraavasti:
\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}
Huomaa, että yksi poluista sisältää vain solmun 2,
eli on sallittua, että polussa ei ole kaaria.
Polkupeitteen etsiminen voidaan tulkita paritusongelmana
verkossa, jossa jokaista alkuperäisen verkon solmua
vastaa kaksi solmua: vasen ja oikea solmu.
Vasemmasta solmusta oikeaan solmuun on kaari,
jos tällainen kaari esiintyy alkuperäisessä verkossa.
Ideana on, että paritus määrittää, mitkä solmut
ovat yhteydessä toisiinsa poluissa.
Esimerkkiverkossa tilanne on seuraava:
\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}
Tässä tapauksessa maksimiparitukseen kuuluu neljä kaarta,
jotka vastaavat alkuperäisen verkon kaaria
$1 \rightarrow 5$, $3 \rightarrow 4$,
$5 \rightarrow 6$ ja $6 \rightarrow 7$.
Niinpä pienin solmuerillinen polkupeite syntyy muodostamalla
polut kyseisten kaarten avulla.
Pienimmän polkupeitteen koko on $n-c$, jossa $n$ on verkon
solmujen määrä ja $c$ on maksimiparituksen kaarten määrä.
Esimerkiksi yllä olevassa verkossa pienimmän
polkupeitteen koko on $7-4=3$.
\subsubsection{Yleinen peite}
Yleisessä polkupeitteessä sama solmu voi kuulua moneen polkuun,
minkä ansiosta tarvittava polkujen määrä saattaa olla pienempi.
Esimerkkiverkossa pienin yleinen polkupeite muodostuu
kahdesta polusta seuraavasti:
\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}
Tässä verkossä yleisessä polkupeitteessä on 2 polkua,
kun taas solmuerillisessä polkupeitteessä on 3 polkua.
Erona on, että yleisessä polkupeitteessä solmua 6
käytetään kahdessa polussa.
Yleisen polkupeitteen voi löytää lähes samalla
tavalla kuin solmuerillisen polkupeitteen.
Riittää täydentää maksimiparituksen verkkoa niin,
että siinä on kaari $a \rightarrow b$ aina silloin,
kun alkuperäisessä verkossa solmusta $a$ pääsee
solmuun $b$ (mahdollisesti usean kaaren kautta).
Nyt esimerkkiverkossa on seuraava tilanne:
\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{Dilworthin lause}
\index{Dilworthin lause@Dilworthin lause}
\index{antiketju@antiketju}
\key{Dilworthin lauseen} mukaan suunnatun, syklittömän
verkon pienin yleinen polkupeite
on yhtä suuri kuin suurin verkossa oleva \key{antiketju}
eli kokoelma solmuja,
jossa minkään kahden solmun välillä ei ole polkua.
Esimerkiksi äskeisessä verkossa pienin
yleinen polkupeite sisältää kaksi polkua,
joten verkon suurimmassa antiketjussa on kaksi solmua.
Tällainen antiketju muodostuu esimerkiksi
valitsemalla solmut 3 ja 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}
Verkossa ei ole polkua solmusta 3 solmuun 7
eikä polkua solmusta 7 solmuun 3,
joten valinta on kelvollinen.
Toisaalta jos verkosta valitaan mitkä tahansa
kolme solmua, jostain solmusta toiseen on polku.