1366 lines
50 KiB
TeX
1366 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{Rinnakkaiset polut}
|
||
|
||
Ensimmäisenä virtauslaskennan sovelluksena tarkastelemme
|
||
tehtävää, jossa tavoitteena on muodostaa mahdollisimman
|
||
monta rinnakkaista polkua verkon alkusolmusta loppusolmuun.
|
||
Vaatimuksena on, että jokainen verkon kaari esiintyy
|
||
enintään yhdellä polulla.
|
||
|
||
Esimerkiksi verkossa
|
||
\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}
|
||
pystyy muodostamaan kaksi rinnakkaista polkua solmusta 1 solmuun 6.
|
||
Tämä toteutuu valitsemalla polut
|
||
$1 \rightarrow 2 \rightarrow 4 \rightarrow 3 \rightarrow 6$
|
||
ja $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}
|
||
|
||
Osoittautuu, että suurin rinnakkaisten polkujen määrä
|
||
on yhtä suuri kuin maksimivirtaus verkossa,
|
||
jossa jokaisen kaaren kapasiteetti on 1.
|
||
Kun maksimivirtaus on muodostettu,
|
||
rinnakkaiset polut voi löytää
|
||
ahneesti etsimällä alkusolmusta loppusolmuun
|
||
kulkevia polkuja.
|
||
|
||
Tarkastellaan sitten tehtävän muunnelmaa,
|
||
jossa jokainen solmu (alku- ja loppusolmua lukuun ottamatta)
|
||
saa esiintyä enintään yhdellä polulla.
|
||
Tämän rajoituksen seurauksena äskeisessä verkossa
|
||
voi muodostaa vain yhden polun,
|
||
koska solmu 4 ei voi esiintyä monella polulla:
|
||
|
||
\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}
|
||
|
||
Tavallinen keino rajoittaa solmun kautta kulkevaa
|
||
virtausta on jakaa solmu tulosolmuksi ja lähtösolmuksi.
|
||
Kaikki solmuun tulevat kaaret saapuvat tulosolmuun
|
||
ja kaikki solmusta lähtevät kaaret poistuvat lähtösolmusta.
|
||
Lisäksi tulosolmusta lähtösolmuun on kaari,
|
||
jossa on haluttu kapasiteetti.
|
||
|
||
Tässä tapauksessa verkosta tulee seuraava:
|
||
\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}
|
||
|
||
Tämän verkon maksimivirtaus on:
|
||
\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}
|
||
|
||
Tämä tarkoittaa, että verkossa on mahdollista muodostaa
|
||
vain yksi polku alkusolmusta lähtösolmuun,
|
||
kun sama solmu ei saa esiintyä monessa polussa.
|
||
|
||
\section{Maksimiparitus}
|
||
|
||
\index{paritus@paritus}
|
||
\index{maksimiparitus@maksimiparitus}
|
||
|
||
\key{Maksimiparitus} on suurin mahdollinen joukko
|
||
verkon solmuista muodostettuja pareja,
|
||
jolle pätee,
|
||
että jokaisen parin välillä on kaari verkossa
|
||
ja jokainen solmu kuuluu enintään yhteen pariin.
|
||
|
||
Maksimiparituksen etsimiseen yleisessä
|
||
verkossa on olemassa polynominen algoritmi,
|
||
mutta se on hyvin monimutkainen.
|
||
Tässä luvussa keskitymmekin tilanteeseen,
|
||
jossa verkko on kaksijakoinen.
|
||
Tällöin maksimiparituksen pystyy etsimään
|
||
helposti virtauslaskennan avulla.
|
||
|
||
\subsubsection{Maksimiparituksen etsiminen}
|
||
|
||
Kaksijakoinen verkko voidaan esittää niin,
|
||
että se muodostuu vasemman ja oikean puolen
|
||
solmuista ja kaikki verkon kaaret kulkevat puolten välillä.
|
||
Tarkastellaan esimerkkinä seuraavaa verkkoa:
|
||
|
||
\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}
|
||
|
||
Tässä verkossa maksimiparituksen koko on 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}
|
||
|
||
Kaksijakoisen verkon maksimiparitus
|
||
vastaa maksimivirtausta verkossa,
|
||
johon on lisätty alkusolmu ja loppusolmu.
|
||
Alkusolmusta on kaari jokaiseen vasemman
|
||
puolen solmuun, ja vastaavasti loppusolmuun
|
||
on kaari jokaisesta oikean puolen solmusta.
|
||
Jokaisen kaaren kapasiteettina on 1.
|
||
|
||
Esimerkissä tuloksena on seuraava verkko:
|
||
|
||
\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}
|
||
|
||
Tämän verkon maksimivirtaus on yhtä suuri kuin
|
||
alkuperäisen verkon maksimiparitus,
|
||
koska virtaus muodostuu joukosta polkuja
|
||
alkusolmusta loppusolmuun ja jokainen
|
||
polku ottaa mukaan uuden kaaren paritukseen.
|
||
Tässä tapauksessa maksimivirtaus on 3,
|
||
joten maksimiparitus on myös 3.
|
||
|
||
\subsubsection{Hallin lause}
|
||
|
||
\index{Hallin lause@Hallin lause}
|
||
\index{txydellinen paritus@täydellinen paritus}
|
||
|
||
\key{Hallin lause} antaa ehdon, milloin kaksijakoiseen
|
||
verkkoon voidaan muodostaa paritus,
|
||
joka sisältää kaikki toisen puolen solmut.
|
||
Jos kummallakin puolella on yhtä monta solmua,
|
||
Hallin lause kertoo, voidaanko muodostaa
|
||
\key{täydellinen paritus},
|
||
jossa kaikki solmut paritetaan keskenään.
|
||
|
||
Oletetaan, että haluamme muodostaa parituksen,
|
||
johon kuuluvat kaikki vasemman puolen solmut.
|
||
Olkoon $X$ jokin joukko vasemman puolen solmuja
|
||
ja $f(X)$ näiden solmujen naapurien joukko.
|
||
Hallin lauseen mukaan paritus on mahdollinen,
|
||
kun jokaiselle joukolle $X$
|
||
pätee $|X| \le |f(X)|$.
|
||
|
||
Tarkastellaan Hallin lauseen merkitystä esimerkkiverkossa.
|
||
Valitaan ensin $X=\{1,3\}$, jolloin $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}
|
||
|
||
Tämä täyttää Hallin lauseen ehdon, koska $|X|=2$ ja $|f(X)|=3$.
|
||
Valitaan sitten $X=\{2,4\}$, jolloin $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}
|
||
|
||
Tässä tapauksessa $|X|=2$ ja $|f(X)|=1$, joten Hallin lauseen ehto
|
||
ei ole voimassa.
|
||
Tämä tarkoittaa, että verkossa
|
||
ei ole mahdollista muodostaa täydellistä paritusta,
|
||
johon kuuluvat kaikki vasemman puolen solmut.
|
||
Tämä on myös odotettu tulos, koska verkon maksimiparitus on 3 eikä 4.
|
||
|
||
Jos Hallin lauseen ehto ei päde, osajoukko $X$
|
||
kertoo syyn sille, miksi paritusta ei voi muodostaa.
|
||
Koska $X$ sisältää enemmän solmuja kuin $f(X)$,
|
||
kaikille $X$:n solmuille ei riitä paria oikealta.
|
||
Esimerkiksi yllä molemmat solmut 2 ja 4 tulisi
|
||
yhdistää solmuun 7, mutta tämä ei ole mahdollista.
|
||
|
||
\subsubsection{Kőnigin lause}
|
||
|
||
\index{Kőnigin lause}
|
||
\index{solmupeite@solmupeite}
|
||
\index{pienin solmupeite@pienin solmupeite}
|
||
|
||
\key{Kőnigin lause} tarjoaa tehokkaan
|
||
tavan muodostaa kaksijakoiselle verkolle
|
||
\key{pienin solmupeite} eli pienin sellainen
|
||
solmujen joukko, että jokaisesta verkon kaaresta ainakin
|
||
toinen päätesolmuista kuuluu joukkoon.
|
||
|
||
Yleisessä verkossa pienimmän solmupeitteen
|
||
etsiminen on NP-vaikea ongelma.
|
||
Sen sijaan kaksijakoisessa verkossa
|
||
Kőnigin lauseen nojalla maksimiparitus ja
|
||
pienin solmupeite ovat aina yhtä suuria,
|
||
minkä ansiosta
|
||
pienimmän solmupeitteen voi
|
||
etsiä tehokkaasti virtauslaskennan avulla.
|
||
|
||
Tarkastellaan taas seuraavaa verkkoa,
|
||
jonka maksimiparituksen koko on 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}
|
||
Kőnigin lauseen ansiosta tiedämme nyt,
|
||
että myös pienimmän solmupeitteen koko on 3.
|
||
Solmupeite voidaan muodostaa seuraavasti:
|
||
|
||
\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}
|
||
Pienin solmupeite muodostuu aina niin,
|
||
että jokaisesta maksimiparituksen kaaresta
|
||
toinen kaaren päätesolmuista kuuluu peitteeseen.
|
||
|
||
\index{riippumaton joukko@riippumaton joukko}
|
||
\index{suurin riippumaton joukko@suurin riippumaton joukko}
|
||
|
||
Kun verkosta valitaan kaikki solmut,
|
||
jotka \emph{eivät} kuulu pienimpään
|
||
solmupeitteeseen, syntyy
|
||
\key{suurin riippumaton joukko}.
|
||
Tämä on suurin mahdollinen joukko solmuja,
|
||
jossa minkään kahden solmun
|
||
välillä ei ole kaarta.
|
||
Pienimmän solmupeitteen tavoin
|
||
riippumattoman joukon muodostaminen on
|
||
NP-vaikea ongelma yleisessä verkossa,
|
||
mutta Kőnigin lauseen avulla
|
||
ongelma on mahdollista ratkaista
|
||
tehokkaasti kaksijakoisessa verkossa.
|
||
Esimerkkiverkossa suurin riippumaton joukko on seuraava:
|
||
|
||
\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.
|
||
|