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 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.
|
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 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.
|
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 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:
|
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 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.
|
2016-12-28 23:54:51 +01:00
|
|
|
|
|
|
|
|
|
\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.
|
|
|
|
|
|