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
|
|
|
|
|
2017-01-10 22:34:36 +01:00
|
|
|
|
\section{Parallel paths}
|
2016-12-28 23:54:51 +01:00
|
|
|
|
|
2017-01-10 22:34:36 +01:00
|
|
|
|
As a first application for flows,
|
|
|
|
|
we consider a problem where the task is to
|
|
|
|
|
form as many parallel paths as possible
|
|
|
|
|
from the starting node of the graph
|
|
|
|
|
to the ending node.
|
|
|
|
|
It is required that no edge appears
|
|
|
|
|
in more than one path.
|
2016-12-28 23:54:51 +01:00
|
|
|
|
|
2017-01-10 22:34:36 +01:00
|
|
|
|
For example, in the graph
|
2016-12-28 23:54:51 +01:00
|
|
|
|
\begin{center}
|
|
|
|
|
\begin{tikzpicture}[scale=0.9]
|
|
|
|
|
\node[draw, circle] (1) at (1,2) {$1$};
|
|
|
|
|
\node[draw, circle] (2) at (3,3) {$2$};
|
|
|
|
|
\node[draw, circle] (3) at (5,3) {$3$};
|
|
|
|
|
\node[draw, circle] (4) at (3,1) {$4$};
|
|
|
|
|
\node[draw, circle] (5) at (5,1) {$5$};
|
|
|
|
|
\node[draw, circle] (6) at (7,2) {$6$};
|
|
|
|
|
\path[draw,thick,->] (1) -- (2);
|
|
|
|
|
\path[draw,thick,->] (1) -- (4);
|
|
|
|
|
\path[draw,thick,->] (2) -- (4);
|
|
|
|
|
\path[draw,thick,->] (3) -- (2);
|
|
|
|
|
\path[draw,thick,->] (3) -- (5);
|
|
|
|
|
\path[draw,thick,->] (3) -- (6);
|
|
|
|
|
\path[draw,thick,->] (4) -- (3);
|
|
|
|
|
\path[draw,thick,->] (4) -- (5);
|
|
|
|
|
\path[draw,thick,->] (5) -- (6);
|
|
|
|
|
\end{tikzpicture}
|
|
|
|
|
\end{center}
|
2017-01-10 22:34:36 +01:00
|
|
|
|
we can form two parallel paths from node 1 to node 6.
|
|
|
|
|
This can be done by choosing paths
|
2016-12-28 23:54:51 +01:00
|
|
|
|
$1 \rightarrow 2 \rightarrow 4 \rightarrow 3 \rightarrow 6$
|
2017-01-10 22:34:36 +01:00
|
|
|
|
and $1 \rightarrow 4 \rightarrow 5 \rightarrow 6$:
|
2016-12-28 23:54:51 +01:00
|
|
|
|
|
|
|
|
|
\begin{center}
|
|
|
|
|
\begin{tikzpicture}[scale=0.9]
|
|
|
|
|
\node[draw, circle] (1) at (1,2) {$1$};
|
|
|
|
|
\node[draw, circle] (2) at (3,3) {$2$};
|
|
|
|
|
\node[draw, circle] (3) at (5,3) {$3$};
|
|
|
|
|
\node[draw, circle] (4) at (3,1) {$4$};
|
|
|
|
|
\node[draw, circle] (5) at (5,1) {$5$};
|
|
|
|
|
\node[draw, circle] (6) at (7,2) {$6$};
|
|
|
|
|
\path[draw,thick,->] (1) -- (2);
|
|
|
|
|
\path[draw,thick,->] (1) -- (4);
|
|
|
|
|
\path[draw,thick,->] (2) -- (4);
|
|
|
|
|
\path[draw,thick,->] (3) -- (2);
|
|
|
|
|
\path[draw,thick,->] (3) -- (5);
|
|
|
|
|
\path[draw,thick,->] (3) -- (6);
|
|
|
|
|
\path[draw,thick,->] (4) -- (3);
|
|
|
|
|
\path[draw,thick,->] (4) -- (5);
|
|
|
|
|
\path[draw,thick,->] (5) -- (6);
|
|
|
|
|
|
|
|
|
|
\path[draw=green,thick,->,line width=2pt] (1) -- (2);
|
|
|
|
|
\path[draw=green,thick,->,line width=2pt] (2) -- (4);
|
|
|
|
|
\path[draw=green,thick,->,line width=2pt] (4) -- (3);
|
|
|
|
|
\path[draw=green,thick,->,line width=2pt] (3) -- (6);
|
|
|
|
|
|
|
|
|
|
\path[draw=blue,thick,->,line width=2pt] (1) -- (4);
|
|
|
|
|
\path[draw=blue,thick,->,line width=2pt] (4) -- (5);
|
|
|
|
|
\path[draw=blue,thick,->,line width=2pt] (5) -- (6);
|
|
|
|
|
\end{tikzpicture}
|
|
|
|
|
\end{center}
|
|
|
|
|
|
2017-01-10 22:34:36 +01:00
|
|
|
|
It turns out that the maximum number of parallel paths
|
|
|
|
|
equals the maximum flow in the graph when the weight
|
|
|
|
|
of each edge is 1.
|
|
|
|
|
After the maximum flow has been constructed,
|
|
|
|
|
the parallel paths can be found greedily by finding
|
|
|
|
|
paths from the starting node to the ending node.
|
|
|
|
|
|
|
|
|
|
Let's then consider a variation for the problem
|
|
|
|
|
where each node (except for the starting and ending nodes)
|
|
|
|
|
can appear in at most one path.
|
|
|
|
|
After this restriction, we can construct only one path
|
|
|
|
|
in the above graph, because node 4 can't appear
|
|
|
|
|
in more than one path:
|
2016-12-28 23:54:51 +01:00
|
|
|
|
|
|
|
|
|
\begin{center}
|
|
|
|
|
\begin{tikzpicture}
|
|
|
|
|
\node[draw, circle] (1) at (1,2) {$1$};
|
|
|
|
|
\node[draw, circle] (2) at (3,3) {$2$};
|
|
|
|
|
\node[draw, circle] (3) at (5,3) {$3$};
|
|
|
|
|
\node[draw, circle] (4) at (3,1) {$4$};
|
|
|
|
|
\node[draw, circle] (5) at (5,1) {$5$};
|
|
|
|
|
\node[draw, circle] (6) at (7,2) {$6$};
|
|
|
|
|
\path[draw,thick,->] (1) -- (2);
|
|
|
|
|
\path[draw,thick,->] (1) -- (4);
|
|
|
|
|
\path[draw,thick,->] (2) -- (4);
|
|
|
|
|
\path[draw,thick,->] (3) -- (2);
|
|
|
|
|
\path[draw,thick,->] (3) -- (5);
|
|
|
|
|
\path[draw,thick,->] (3) -- (6);
|
|
|
|
|
\path[draw,thick,->] (4) -- (3);
|
|
|
|
|
\path[draw,thick,->] (4) -- (5);
|
|
|
|
|
\path[draw,thick,->] (5) -- (6);
|
|
|
|
|
|
|
|
|
|
\path[draw=green,thick,->,line width=2pt] (1) -- (2);
|
|
|
|
|
\path[draw=green,thick,->,line width=2pt] (2) -- (4);
|
|
|
|
|
\path[draw=green,thick,->,line width=2pt] (4) -- (3);
|
|
|
|
|
\path[draw=green,thick,->,line width=2pt] (3) -- (6);
|
|
|
|
|
\end{tikzpicture}
|
|
|
|
|
\end{center}
|
|
|
|
|
|
2017-01-10 22:34:36 +01:00
|
|
|
|
A standard way to restrict the flow through a node
|
|
|
|
|
is to divide the node into two parts.
|
|
|
|
|
All incoming edges are connected to the first part,
|
|
|
|
|
and all outgoing edges are connected to the second part.
|
|
|
|
|
In addition, there is an edge from the first part
|
|
|
|
|
to the second part.
|
2016-12-28 23:54:51 +01:00
|
|
|
|
|
2017-01-10 22:34:36 +01:00
|
|
|
|
In the current example, the graph becomes as follows:
|
2016-12-28 23:54:51 +01:00
|
|
|
|
\begin{center}
|
|
|
|
|
\begin{tikzpicture}
|
|
|
|
|
\node[draw, circle] (1) at (1,2) {$1$};
|
|
|
|
|
|
|
|
|
|
\node[draw, circle] (2a) at (3,3) {$2$};
|
|
|
|
|
\node[draw, circle] (3a) at (6,3) {$3$};
|
|
|
|
|
\node[draw, circle] (4a) at (3,1) {$4$};
|
|
|
|
|
\node[draw, circle] (5a) at (6,1) {$5$};
|
|
|
|
|
|
|
|
|
|
\node[draw, circle] (2b) at (4,3) {$2$};
|
|
|
|
|
\node[draw, circle] (3b) at (7,3) {$3$};
|
|
|
|
|
\node[draw, circle] (4b) at (4,1) {$4$};
|
|
|
|
|
\node[draw, circle] (5b) at (7,1) {$5$};
|
|
|
|
|
|
|
|
|
|
\node[draw, circle] (6) at (9,2) {$6$};
|
|
|
|
|
|
|
|
|
|
\path[draw,thick,->] (2a) -- (2b);
|
|
|
|
|
\path[draw,thick,->] (3a) -- (3b);
|
|
|
|
|
\path[draw,thick,->] (4a) -- (4b);
|
|
|
|
|
\path[draw,thick,->] (5a) -- (5b);
|
|
|
|
|
|
|
|
|
|
\path[draw,thick,->] (1) -- (2a);
|
|
|
|
|
\path[draw,thick,->] (1) -- (4a);
|
|
|
|
|
\path[draw,thick,->] (2b) -- (4a);
|
|
|
|
|
\path[draw,thick,->] (3b) edge [bend right=30] (2a);
|
|
|
|
|
\path[draw,thick,->] (3b) -- (5a);
|
|
|
|
|
\path[draw,thick,->] (3b) -- (6);
|
|
|
|
|
\path[draw,thick,->] (4b) -- (3a);
|
|
|
|
|
\path[draw,thick,->] (4b) -- (5a);
|
|
|
|
|
\path[draw,thick,->] (5b) -- (6);
|
|
|
|
|
\end{tikzpicture}
|
|
|
|
|
\end{center}
|
|
|
|
|
|
2017-01-10 22:34:36 +01:00
|
|
|
|
The maximum flow for the graph is as follows:
|
2016-12-28 23:54:51 +01:00
|
|
|
|
\begin{center}
|
|
|
|
|
\begin{tikzpicture}
|
|
|
|
|
\node[draw, circle] (1) at (1,2) {$1$};
|
|
|
|
|
|
|
|
|
|
\node[draw, circle] (2a) at (3,3) {$2$};
|
|
|
|
|
\node[draw, circle] (3a) at (6,3) {$3$};
|
|
|
|
|
\node[draw, circle] (4a) at (3,1) {$4$};
|
|
|
|
|
\node[draw, circle] (5a) at (6,1) {$5$};
|
|
|
|
|
|
|
|
|
|
\node[draw, circle] (2b) at (4,3) {$2$};
|
|
|
|
|
\node[draw, circle] (3b) at (7,3) {$3$};
|
|
|
|
|
\node[draw, circle] (4b) at (4,1) {$4$};
|
|
|
|
|
\node[draw, circle] (5b) at (7,1) {$5$};
|
|
|
|
|
|
|
|
|
|
\node[draw, circle] (6) at (9,2) {$6$};
|
|
|
|
|
|
|
|
|
|
\path[draw,thick,->] (2a) -- (2b);
|
|
|
|
|
\path[draw,thick,->] (3a) -- (3b);
|
|
|
|
|
\path[draw,thick,->] (4a) -- (4b);
|
|
|
|
|
\path[draw,thick,->] (5a) -- (5b);
|
|
|
|
|
|
|
|
|
|
\path[draw,thick,->] (1) -- (2a);
|
|
|
|
|
\path[draw,thick,->] (1) -- (4a);
|
|
|
|
|
\path[draw,thick,->] (2b) -- (4a);
|
|
|
|
|
\path[draw,thick,->] (3b) edge [bend right=30] (2a);
|
|
|
|
|
\path[draw,thick,->] (3b) -- (5a);
|
|
|
|
|
\path[draw,thick,->] (3b) -- (6);
|
|
|
|
|
\path[draw,thick,->] (4b) -- (3a);
|
|
|
|
|
\path[draw,thick,->] (4b) -- (5a);
|
|
|
|
|
\path[draw,thick,->] (5b) -- (6);
|
|
|
|
|
|
|
|
|
|
\path[draw=red,thick,->,line width=2pt] (1) -- (2a);
|
|
|
|
|
\path[draw=red,thick,->,line width=2pt] (2a) -- (2b);
|
|
|
|
|
\path[draw=red,thick,->,line width=2pt] (2b) -- (4a);
|
|
|
|
|
\path[draw=red,thick,->,line width=2pt] (4a) -- (4b);
|
|
|
|
|
\path[draw=red,thick,->,line width=2pt] (4b) -- (3a);
|
|
|
|
|
\path[draw=red,thick,->,line width=2pt] (3a) -- (3b);
|
|
|
|
|
\path[draw=red,thick,->,line width=2pt] (3b) -- (6);
|
|
|
|
|
\end{tikzpicture}
|
|
|
|
|
\end{center}
|
|
|
|
|
|
2017-01-10 22:34:36 +01:00
|
|
|
|
This means that it is possible to form exactly
|
|
|
|
|
one path from the starting node to the ending node
|
|
|
|
|
when a node can't appear in more than one path.
|
2016-12-28 23:54:51 +01:00
|
|
|
|
|
2017-01-10 22:34:36 +01:00
|
|
|
|
\section{Maximum matching}
|
2016-12-28 23:54:51 +01:00
|
|
|
|
|
2017-01-10 22:34:36 +01:00
|
|
|
|
\index{matching}
|
|
|
|
|
\index{maximum matching}
|
2016-12-28 23:54:51 +01:00
|
|
|
|
|
2017-01-10 22:34:36 +01:00
|
|
|
|
A \key{maximum matching} is the largest possible
|
|
|
|
|
set of pairs of nodes in a graph
|
|
|
|
|
such that there is an edge between each pair of nodes,
|
|
|
|
|
and each node belongs to at most one pair.
|
2016-12-28 23:54:51 +01:00
|
|
|
|
|
2017-01-10 22:34:36 +01:00
|
|
|
|
There is a polynomial algorithm for finding
|
|
|
|
|
a maximum matching in a general graph,
|
|
|
|
|
but it is very complex.
|
|
|
|
|
For this reason, we will restrict ourselves to the
|
|
|
|
|
case where the graph is bipartite.
|
|
|
|
|
In this case we can easily find the maximum matching
|
|
|
|
|
using a maximum flow algorithm.
|
2016-12-28 23:54:51 +01:00
|
|
|
|
|
2017-01-10 22:34:36 +01:00
|
|
|
|
\subsubsection{Finding a maximum matching}
|
2016-12-28 23:54:51 +01:00
|
|
|
|
|
2017-01-10 22:34:36 +01:00
|
|
|
|
A bipartite graph can be always presented so
|
|
|
|
|
that it consists of left-side and right-side nodes,
|
|
|
|
|
and all edges in the graph go between
|
|
|
|
|
left and right sides.
|
|
|
|
|
As an example, consider the following graph:
|
2016-12-28 23:54:51 +01:00
|
|
|
|
|
|
|
|
|
\begin{center}
|
|
|
|
|
\begin{tikzpicture}[scale=0.60]
|
|
|
|
|
\node[draw, circle] (1) at (2,4.5) {1};
|
|
|
|
|
\node[draw, circle] (2) at (2,3) {2};
|
|
|
|
|
\node[draw, circle] (3) at (2,1.5) {3};
|
|
|
|
|
\node[draw, circle] (4) at (2,0) {4};
|
|
|
|
|
\node[draw, circle] (5) at (8,4.5) {5};
|
|
|
|
|
\node[draw, circle] (6) at (8,3) {6};
|
|
|
|
|
\node[draw, circle] (7) at (8,1.5) {7};
|
|
|
|
|
\node[draw, circle] (8) at (8,0) {8};
|
|
|
|
|
|
|
|
|
|
\path[draw,thick,-] (1) -- (5);
|
|
|
|
|
\path[draw,thick,-] (2) -- (7);
|
|
|
|
|
\path[draw,thick,-] (3) -- (5);
|
|
|
|
|
\path[draw,thick,-] (3) -- (6);
|
|
|
|
|
\path[draw,thick,-] (3) -- (8);
|
|
|
|
|
\path[draw,thick,-] (4) -- (7);
|
|
|
|
|
\end{tikzpicture}
|
|
|
|
|
\end{center}
|
|
|
|
|
|
2017-01-10 22:34:36 +01:00
|
|
|
|
In this graph, the size of a maximum matching is 3:
|
2016-12-28 23:54:51 +01:00
|
|
|
|
\begin{center}
|
|
|
|
|
\begin{tikzpicture}[scale=0.60]
|
|
|
|
|
\node[draw, circle] (1) at (2,4.5) {1};
|
|
|
|
|
\node[draw, circle] (2) at (2,3) {2};
|
|
|
|
|
\node[draw, circle] (3) at (2,1.5) {3};
|
|
|
|
|
\node[draw, circle] (4) at (2,0) {4};
|
|
|
|
|
\node[draw, circle] (5) at (8,4.5) {5};
|
|
|
|
|
\node[draw, circle] (6) at (8,3) {6};
|
|
|
|
|
\node[draw, circle] (7) at (8,1.5) {7};
|
|
|
|
|
\node[draw, circle] (8) at (8,0) {8};
|
|
|
|
|
|
|
|
|
|
\path[draw,thick,-] (1) -- (5);
|
|
|
|
|
\path[draw,thick,-] (2) -- (7);
|
|
|
|
|
\path[draw,thick,-] (3) -- (5);
|
|
|
|
|
\path[draw,thick,-] (3) -- (6);
|
|
|
|
|
\path[draw,thick,-] (3) -- (8);
|
|
|
|
|
\path[draw,thick,-] (4) -- (7);
|
|
|
|
|
|
|
|
|
|
\path[draw=red,thick,-,line width=2pt] (1) -- (5);
|
|
|
|
|
\path[draw=red,thick,-,line width=2pt] (2) -- (7);
|
|
|
|
|
\path[draw=red,thick,-,line width=2pt] (3) -- (6);
|
|
|
|
|
\end{tikzpicture}
|
|
|
|
|
\end{center}
|
|
|
|
|
|
2017-01-10 22:34:36 +01:00
|
|
|
|
A maximum matching in a bipartite graph
|
|
|
|
|
corresponds to a maximum flow in an extended graph
|
|
|
|
|
that contains a starting node,
|
|
|
|
|
an ending node and all the nodes of the original graph.
|
|
|
|
|
There is an edge from the starting node to
|
|
|
|
|
each left-side node, and an edge from
|
|
|
|
|
each right-side node to the ending node.
|
|
|
|
|
The capacity of each edge is 1.
|
2016-12-28 23:54:51 +01:00
|
|
|
|
|
2017-01-10 22:34:36 +01:00
|
|
|
|
In the example graph, the result is as follows:
|
2016-12-28 23:54:51 +01:00
|
|
|
|
\begin{center}
|
|
|
|
|
\begin{tikzpicture}[scale=0.60]
|
|
|
|
|
\node[draw, circle] (1) at (2,4.5) {1};
|
|
|
|
|
\node[draw, circle] (2) at (2,3) {2};
|
|
|
|
|
\node[draw, circle] (3) at (2,1.5) {3};
|
|
|
|
|
\node[draw, circle] (4) at (2,0) {4};
|
|
|
|
|
\node[draw, circle] (5) at (8,4.5) {5};
|
|
|
|
|
\node[draw, circle] (6) at (8,3) {6};
|
|
|
|
|
\node[draw, circle] (7) at (8,1.5) {7};
|
|
|
|
|
\node[draw, circle] (8) at (8,0) {8};
|
|
|
|
|
|
|
|
|
|
\node[draw, circle] (a) at (-2,2.25) {\phantom{0}};
|
|
|
|
|
\node[draw, circle] (b) at (12,2.25) {\phantom{0}};
|
|
|
|
|
|
|
|
|
|
\path[draw,thick,->] (1) -- (5);
|
|
|
|
|
\path[draw,thick,->] (2) -- (7);
|
|
|
|
|
\path[draw,thick,->] (3) -- (5);
|
|
|
|
|
\path[draw,thick,->] (3) -- (6);
|
|
|
|
|
\path[draw,thick,->] (3) -- (8);
|
|
|
|
|
\path[draw,thick,->] (4) -- (7);
|
|
|
|
|
|
|
|
|
|
\path[draw,thick,->] (a) -- (1);
|
|
|
|
|
\path[draw,thick,->] (a) -- (2);
|
|
|
|
|
\path[draw,thick,->] (a) -- (3);
|
|
|
|
|
\path[draw,thick,->] (a) -- (4);
|
|
|
|
|
\path[draw,thick,->] (5) -- (b);
|
|
|
|
|
\path[draw,thick,->] (6) -- (b);
|
|
|
|
|
\path[draw,thick,->] (7) -- (b);
|
|
|
|
|
\path[draw,thick,->] (8) -- (b);
|
|
|
|
|
\end{tikzpicture}
|
|
|
|
|
\end{center}
|
|
|
|
|
|
2017-01-10 22:34:36 +01:00
|
|
|
|
The size of a maximum flow in this graph
|
|
|
|
|
equals the size of a maximum matching
|
|
|
|
|
in the original graph,
|
|
|
|
|
because each path from the starting node
|
|
|
|
|
to the ending node adds one edge to the matching.
|
|
|
|
|
In this graph, the maximum flow is 3,
|
|
|
|
|
so the maximum matching is also 3.
|
|
|
|
|
|
|
|
|
|
\subsubsection{Hall's theorem}
|
|
|
|
|
|
|
|
|
|
\index{Hall's theorem}
|
|
|
|
|
\index{perfect matching}
|
|
|
|
|
|
|
|
|
|
\key{Hall's theorem} describes when a bipartite graph
|
|
|
|
|
has a matching that contains all nodes
|
|
|
|
|
in one side of the graph.
|
|
|
|
|
If both sides contain the same number of nodes,
|
|
|
|
|
Hall's theorem tells us if it's possible to
|
|
|
|
|
construct a \key{perfect matching} where
|
|
|
|
|
all nodes are paired with each other.
|
|
|
|
|
|
|
|
|
|
Assume that we want to construct a matching
|
|
|
|
|
that contains all left-side nodes.
|
|
|
|
|
Let $X$ be a set of left-side nodes,
|
|
|
|
|
and let $f(X)$ be the set of their neighbors.
|
|
|
|
|
According to Hall's theorem, a such matching exists
|
|
|
|
|
exactly when for each $X$, the condition $|X| \le |f(X)|$ holds.
|
|
|
|
|
|
|
|
|
|
Let's study Hall's theorem in the example graph.
|
|
|
|
|
First, let $X=\{1,3\}$ and $f(X)=\{5,6,8\}$:
|
2016-12-28 23:54:51 +01:00
|
|
|
|
|
|
|
|
|
\begin{center}
|
|
|
|
|
\begin{tikzpicture}[scale=0.60]
|
|
|
|
|
\node[draw, circle, fill=lightgray] (1) at (2,4.5) {1};
|
|
|
|
|
\node[draw, circle] (2) at (2,3) {2};
|
|
|
|
|
\node[draw, circle, fill=lightgray] (3) at (2,1.5) {3};
|
|
|
|
|
\node[draw, circle] (4) at (2,0) {4};
|
|
|
|
|
\node[draw, circle, fill=lightgray] (5) at (8,4.5) {5};
|
|
|
|
|
\node[draw, circle, fill=lightgray] (6) at (8,3) {6};
|
|
|
|
|
\node[draw, circle] (7) at (8,1.5) {7};
|
|
|
|
|
\node[draw, circle, fill=lightgray] (8) at (8,0) {8};
|
|
|
|
|
|
|
|
|
|
\path[draw,thick,-] (1) -- (5);
|
|
|
|
|
\path[draw,thick,-] (2) -- (7);
|
|
|
|
|
\path[draw,thick,-] (3) -- (5);
|
|
|
|
|
\path[draw,thick,-] (3) -- (6);
|
|
|
|
|
\path[draw,thick,-] (3) -- (8);
|
|
|
|
|
\path[draw,thick,-] (4) -- (7);
|
|
|
|
|
\end{tikzpicture}
|
|
|
|
|
\end{center}
|
|
|
|
|
|
2017-01-10 22:34:36 +01:00
|
|
|
|
The condition of Hall's theorem holds, because
|
|
|
|
|
$|X|=2$ and $|f(X)|=3$.
|
|
|
|
|
Next, let $X=\{2,4\}$ and $f(X)=\{7\}$:
|
2016-12-28 23:54:51 +01:00
|
|
|
|
|
|
|
|
|
\begin{center}
|
|
|
|
|
\begin{tikzpicture}[scale=0.60]
|
|
|
|
|
\node[draw, circle] (1) at (2,4.5) {1};
|
|
|
|
|
\node[draw, circle, fill=lightgray] (2) at (2,3) {2};
|
|
|
|
|
\node[draw, circle] (3) at (2,1.5) {3};
|
|
|
|
|
\node[draw, circle, fill=lightgray] (4) at (2,0) {4};
|
|
|
|
|
\node[draw, circle] (5) at (8,4.5) {5};
|
|
|
|
|
\node[draw, circle] (6) at (8,3) {6};
|
|
|
|
|
\node[draw, circle, fill=lightgray] (7) at (8,1.5) {7};
|
|
|
|
|
\node[draw, circle] (8) at (8,0) {8};
|
|
|
|
|
|
|
|
|
|
\path[draw,thick,-] (1) -- (5);
|
|
|
|
|
\path[draw,thick,-] (2) -- (7);
|
|
|
|
|
\path[draw,thick,-] (3) -- (5);
|
|
|
|
|
\path[draw,thick,-] (3) -- (6);
|
|
|
|
|
\path[draw,thick,-] (3) -- (8);
|
|
|
|
|
\path[draw,thick,-] (4) -- (7);
|
|
|
|
|
\end{tikzpicture}
|
|
|
|
|
\end{center}
|
|
|
|
|
|
2017-01-10 22:34:36 +01:00
|
|
|
|
In this case, $|X|=2$ and $|f(X)|=1$,
|
|
|
|
|
so the condition of Hall's theorem doesn't hold.
|
|
|
|
|
This means that it's not possible to form
|
|
|
|
|
a perfect matching in the graph.
|
|
|
|
|
This result is not surprising, because we already
|
|
|
|
|
knew that the maximum matching in the graph is 3 and not 4.
|
|
|
|
|
|
|
|
|
|
If the condition of Hall's theorem doesn't hold,
|
|
|
|
|
the set $X$ provides an explanation why we can't form a matching.
|
|
|
|
|
Since $X$ contains more nodes than $f(X)$,
|
|
|
|
|
there is no pair for all nodes in $X$.
|
|
|
|
|
For example, in the above graph, both nodes 2 and 4
|
|
|
|
|
should be connected to node 7 which is not possible.
|
|
|
|
|
|
|
|
|
|
\subsubsection{Kőnig's theorem}
|
|
|
|
|
|
|
|
|
|
\index{Kőnig's theorem}
|
|
|
|
|
\index{node cover}
|
|
|
|
|
\index{minimum node cover}
|
|
|
|
|
|
|
|
|
|
\key{Kőnig's theorem} provides an efficient way
|
|
|
|
|
to construct a \key{minimum node cover} for a
|
|
|
|
|
bipartite graph.
|
|
|
|
|
This is a minimum set of nodes such that
|
|
|
|
|
each edge in the graph is connected to at least
|
|
|
|
|
one node in the set.
|
|
|
|
|
|
|
|
|
|
In a general graph, finding a minimum node cover
|
|
|
|
|
is a NP-hard problem.
|
|
|
|
|
However, in a bipartite graph,
|
|
|
|
|
the size of
|
|
|
|
|
a maximum matching and a minimum node cover
|
|
|
|
|
is always the same, according to Kőnig's theorem.
|
|
|
|
|
Thus, we can efficiently find a minimum node cover
|
|
|
|
|
using a maximum flow algorithm.
|
|
|
|
|
|
|
|
|
|
Let's consider the following graph
|
|
|
|
|
with a maximum matching of size 3:
|
2016-12-28 23:54:51 +01:00
|
|
|
|
\begin{center}
|
|
|
|
|
\begin{tikzpicture}[scale=0.60]
|
|
|
|
|
\node[draw, circle] (1) at (2,4.5) {1};
|
|
|
|
|
\node[draw, circle] (2) at (2,3) {2};
|
|
|
|
|
\node[draw, circle] (3) at (2,1.5) {3};
|
|
|
|
|
\node[draw, circle] (4) at (2,0) {4};
|
|
|
|
|
\node[draw, circle] (5) at (8,4.5) {5};
|
|
|
|
|
\node[draw, circle] (6) at (8,3) {6};
|
|
|
|
|
\node[draw, circle] (7) at (8,1.5) {7};
|
|
|
|
|
\node[draw, circle] (8) at (8,0) {8};
|
|
|
|
|
|
|
|
|
|
\path[draw,thick,-] (1) -- (5);
|
|
|
|
|
\path[draw,thick,-] (2) -- (7);
|
|
|
|
|
\path[draw,thick,-] (3) -- (5);
|
|
|
|
|
\path[draw,thick,-] (3) -- (6);
|
|
|
|
|
\path[draw,thick,-] (3) -- (8);
|
|
|
|
|
\path[draw,thick,-] (4) -- (7);
|
|
|
|
|
|
|
|
|
|
\path[draw=red,thick,-,line width=2pt] (1) -- (5);
|
|
|
|
|
\path[draw=red,thick,-,line width=2pt] (2) -- (7);
|
|
|
|
|
\path[draw=red,thick,-,line width=2pt] (3) -- (6);
|
|
|
|
|
\end{tikzpicture}
|
|
|
|
|
\end{center}
|
2017-01-10 22:34:36 +01:00
|
|
|
|
Using Kőnig's theorem, we know that the size
|
|
|
|
|
of a minimum node cover is also 3.
|
|
|
|
|
It can be constructed as follows:
|
2016-12-28 23:54:51 +01:00
|
|
|
|
|
|
|
|
|
\begin{center}
|
|
|
|
|
\begin{tikzpicture}[scale=0.60]
|
|
|
|
|
\node[draw, circle, fill=lightgray] (1) at (2,4.5) {1};
|
|
|
|
|
\node[draw, circle] (2) at (2,3) {2};
|
|
|
|
|
\node[draw, circle, fill=lightgray] (3) at (2,1.5) {3};
|
|
|
|
|
\node[draw, circle] (4) at (2,0) {4};
|
|
|
|
|
\node[draw, circle] (5) at (8,4.5) {5};
|
|
|
|
|
\node[draw, circle] (6) at (8,3) {6};
|
|
|
|
|
\node[draw, circle, fill=lightgray] (7) at (8,1.5) {7};
|
|
|
|
|
\node[draw, circle] (8) at (8,0) {8};
|
|
|
|
|
|
|
|
|
|
\path[draw,thick,-] (1) -- (5);
|
|
|
|
|
\path[draw,thick,-] (2) -- (7);
|
|
|
|
|
\path[draw,thick,-] (3) -- (5);
|
|
|
|
|
\path[draw,thick,-] (3) -- (6);
|
|
|
|
|
\path[draw,thick,-] (3) -- (8);
|
|
|
|
|
\path[draw,thick,-] (4) -- (7);
|
|
|
|
|
\end{tikzpicture}
|
|
|
|
|
\end{center}
|
2017-01-10 22:34:36 +01:00
|
|
|
|
For each edge in the maximum matching,
|
|
|
|
|
exactly one of its end nodes belongs to
|
|
|
|
|
the minimum node cover.
|
|
|
|
|
|
|
|
|
|
\index{independent set}
|
|
|
|
|
\index{maximum independent set}
|
|
|
|
|
|
|
|
|
|
The set of all nodes that do \emph{not}
|
|
|
|
|
belong to a minimum node cover
|
|
|
|
|
is a \key{maximum independent set}.
|
|
|
|
|
This is the largest possible set of nodes
|
|
|
|
|
where there is no edge between any two nodes
|
|
|
|
|
in the graph.
|
|
|
|
|
Once again, finding a maximum independent
|
|
|
|
|
set in a general graph is a NP-hard problem,
|
|
|
|
|
but in a bipartite graph we can use
|
|
|
|
|
Kőnig's theorem to solve the problem efficiently.
|
|
|
|
|
In the example graph, the maximum independent
|
|
|
|
|
set is as follows:
|
2016-12-28 23:54:51 +01:00
|
|
|
|
|
|
|
|
|
\begin{center}
|
|
|
|
|
\begin{tikzpicture}[scale=0.60]
|
|
|
|
|
\node[draw, circle] (1) at (2,4.5) {1};
|
|
|
|
|
\node[draw, circle, fill=lightgray] (2) at (2,3) {2};
|
|
|
|
|
\node[draw, circle] (3) at (2,1.5) {3};
|
|
|
|
|
\node[draw, circle, fill=lightgray] (4) at (2,0) {4};
|
|
|
|
|
\node[draw, circle, fill=lightgray] (5) at (8,4.5) {5};
|
|
|
|
|
\node[draw, circle, fill=lightgray] (6) at (8,3) {6};
|
|
|
|
|
\node[draw, circle] (7) at (8,1.5) {7};
|
|
|
|
|
\node[draw, circle, fill=lightgray] (8) at (8,0) {8};
|
|
|
|
|
|
|
|
|
|
\path[draw,thick,-] (1) -- (5);
|
|
|
|
|
\path[draw,thick,-] (2) -- (7);
|
|
|
|
|
\path[draw,thick,-] (3) -- (5);
|
|
|
|
|
\path[draw,thick,-] (3) -- (6);
|
|
|
|
|
\path[draw,thick,-] (3) -- (8);
|
|
|
|
|
\path[draw,thick,-] (4) -- (7);
|
|
|
|
|
\end{tikzpicture}
|
|
|
|
|
\end{center}
|
|
|
|
|
|
|
|
|
|
\section{Polkupeitteet}
|
|
|
|
|
|
|
|
|
|
\index{polkupeite@polkupeite}
|
|
|
|
|
|
|
|
|
|
\key{Polkupeite} on joukko verkon polkuja,
|
|
|
|
|
jotka on valittu niin, että jokainen verkon solmu kuuluu
|
|
|
|
|
ainakin yhteen polkuun.
|
|
|
|
|
Osoittautuu, että voimme muodostaa
|
|
|
|
|
virtauslaskennan avulla
|
|
|
|
|
pienimmän polkupeitteen suunnatussa,
|
|
|
|
|
syklittömässä verkossa.
|
|
|
|
|
|
|
|
|
|
Polkupeitteestä on kaksi muunnelmaa:
|
|
|
|
|
\key{Solmuerillinen peite} on polkupeite,
|
|
|
|
|
jossa jokainen verkon solmu esiintyy tasan yhdessä polussa.
|
|
|
|
|
\key{Yleinen peite} taas on polkupeite, jossa sama solmu voi
|
|
|
|
|
esiintyä useammassa polussa.
|
|
|
|
|
Kummassakin tapauksessa pienin polkupeite löytyy
|
|
|
|
|
samanlaisella idealla.
|
|
|
|
|
|
|
|
|
|
\subsubsection{Solmuerillinen peite}
|
|
|
|
|
|
|
|
|
|
Tarkastellaan esimerkkinä seuraavaa verkkoa:
|
|
|
|
|
|
|
|
|
|
\begin{center}
|
|
|
|
|
\begin{tikzpicture}[scale=0.9]
|
|
|
|
|
\node[draw, circle] (1) at (0,0) {1};
|
|
|
|
|
\node[draw, circle] (2) at (2,0) {2};
|
|
|
|
|
\node[draw, circle] (3) at (4,0) {3};
|
|
|
|
|
\node[draw, circle] (4) at (6,0) {4};
|
|
|
|
|
\node[draw, circle] (5) at (0,-2) {5};
|
|
|
|
|
\node[draw, circle] (6) at (2,-2) {6};
|
|
|
|
|
\node[draw, circle] (7) at (4,-2) {7};
|
|
|
|
|
|
|
|
|
|
\path[draw,thick,->,>=latex] (1) -- (5);
|
|
|
|
|
\path[draw,thick,->,>=latex] (2) -- (6);
|
|
|
|
|
\path[draw,thick,->,>=latex] (3) -- (4);
|
|
|
|
|
\path[draw,thick,->,>=latex] (5) -- (6);
|
|
|
|
|
\path[draw,thick,->,>=latex] (6) -- (3);
|
|
|
|
|
\path[draw,thick,->,>=latex] (6) -- (7);
|
|
|
|
|
\end{tikzpicture}
|
|
|
|
|
\end{center}
|
|
|
|
|
|
|
|
|
|
Tässä tapauksessa pienin solmuerillinen polkupeite
|
|
|
|
|
muodostuu kolmesta polusta.
|
|
|
|
|
Voimme valita polut esimerkiksi seuraavasti:
|
|
|
|
|
|
|
|
|
|
\begin{center}
|
|
|
|
|
\begin{tikzpicture}[scale=0.9]
|
|
|
|
|
\node[draw, circle] (1) at (0,0) {1};
|
|
|
|
|
\node[draw, circle] (2) at (2,0) {2};
|
|
|
|
|
\node[draw, circle] (3) at (4,0) {3};
|
|
|
|
|
\node[draw, circle] (4) at (6,0) {4};
|
|
|
|
|
\node[draw, circle] (5) at (0,-2) {5};
|
|
|
|
|
\node[draw, circle] (6) at (2,-2) {6};
|
|
|
|
|
\node[draw, circle] (7) at (4,-2) {7};
|
|
|
|
|
|
|
|
|
|
\path[draw=red,thick,->,line width=2pt] (1) -- (5);
|
|
|
|
|
\path[draw=red,thick,->,line width=2pt] (5) -- (6);
|
|
|
|
|
\path[draw=red,thick,->,line width=2pt] (6) -- (7);
|
|
|
|
|
\path[draw=red,thick,->,line width=2pt] (3) -- (4);
|
|
|
|
|
\end{tikzpicture}
|
|
|
|
|
\end{center}
|
|
|
|
|
|
|
|
|
|
Huomaa, että yksi poluista sisältää vain solmun 2,
|
|
|
|
|
eli on sallittua, että polussa ei ole kaaria.
|
|
|
|
|
|
|
|
|
|
Polkupeitteen etsiminen voidaan tulkita paritusongelmana
|
|
|
|
|
verkossa, jossa jokaista alkuperäisen verkon solmua
|
|
|
|
|
vastaa kaksi solmua: vasen ja oikea solmu.
|
|
|
|
|
Vasemmasta solmusta oikeaan solmuun on kaari,
|
|
|
|
|
jos tällainen kaari esiintyy alkuperäisessä verkossa.
|
|
|
|
|
Ideana on, että paritus määrittää, mitkä solmut
|
|
|
|
|
ovat yhteydessä toisiinsa poluissa.
|
|
|
|
|
|
|
|
|
|
Esimerkkiverkossa tilanne on seuraava:
|
|
|
|
|
|
|
|
|
|
\begin{center}
|
|
|
|
|
\begin{tikzpicture}[scale=0.9]
|
|
|
|
|
\node[draw, circle] (1a) at (0,6) {1};
|
|
|
|
|
\node[draw, circle] (2a) at (0,5) {2};
|
|
|
|
|
\node[draw, circle] (3a) at (0,4) {3};
|
|
|
|
|
\node[draw, circle] (4a) at (0,3) {4};
|
|
|
|
|
\node[draw, circle] (5a) at (0,2) {5};
|
|
|
|
|
\node[draw, circle] (6a) at (0,1) {6};
|
|
|
|
|
\node[draw, circle] (7a) at (0,0) {7};
|
|
|
|
|
|
|
|
|
|
\node[draw, circle] (1b) at (4,6) {1};
|
|
|
|
|
\node[draw, circle] (2b) at (4,5) {2};
|
|
|
|
|
\node[draw, circle] (3b) at (4,4) {3};
|
|
|
|
|
\node[draw, circle] (4b) at (4,3) {4};
|
|
|
|
|
\node[draw, circle] (5b) at (4,2) {5};
|
|
|
|
|
\node[draw, circle] (6b) at (4,1) {6};
|
|
|
|
|
\node[draw, circle] (7b) at (4,0) {7};
|
|
|
|
|
|
|
|
|
|
\node[draw, circle] (a) at (-3,3) {\phantom{0}};
|
|
|
|
|
\node[draw, circle] (b) at (7,3) {\phantom{0}};
|
|
|
|
|
|
|
|
|
|
%\path[draw,thick,->,>=latex] (1a) -- (5b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (2a) -- (6b);
|
|
|
|
|
%\path[draw,thick,->,>=latex] (3a) -- (4b);
|
|
|
|
|
%\path[draw,thick,->,>=latex] (5a) -- (6b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (6a) -- (3b);
|
|
|
|
|
%\path[draw,thick,->,>=latex] (6a) -- (7b);
|
|
|
|
|
|
|
|
|
|
\path[draw,thick,->,>=latex] (a) -- (1a);
|
|
|
|
|
\path[draw,thick,->,>=latex] (a) -- (2a);
|
|
|
|
|
\path[draw,thick,->,>=latex] (a) -- (3a);
|
|
|
|
|
\path[draw,thick,->,>=latex] (a) -- (4a);
|
|
|
|
|
\path[draw,thick,->,>=latex] (a) -- (5a);
|
|
|
|
|
\path[draw,thick,->,>=latex] (a) -- (6a);
|
|
|
|
|
\path[draw,thick,->,>=latex] (a) -- (7a);
|
|
|
|
|
|
|
|
|
|
\path[draw,thick,->,>=latex] (1b) -- (b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (2b) -- (b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (3b) -- (b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (4b) -- (b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (5b) -- (b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (6b) -- (b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (7b) -- (b);
|
|
|
|
|
|
|
|
|
|
\path[draw=red,thick,->,line width=2pt] (1a) -- (5b);
|
|
|
|
|
\path[draw=red,thick,->,line width=2pt] (5a) -- (6b);
|
|
|
|
|
\path[draw=red,thick,->,line width=2pt] (6a) -- (7b);
|
|
|
|
|
\path[draw=red,thick,->,line width=2pt] (3a) -- (4b);
|
|
|
|
|
|
|
|
|
|
\end{tikzpicture}
|
|
|
|
|
\end{center}
|
|
|
|
|
|
|
|
|
|
Tässä tapauksessa maksimiparitukseen kuuluu neljä kaarta,
|
|
|
|
|
jotka vastaavat alkuperäisen verkon kaaria
|
|
|
|
|
$1 \rightarrow 5$, $3 \rightarrow 4$,
|
|
|
|
|
$5 \rightarrow 6$ ja $6 \rightarrow 7$.
|
|
|
|
|
Niinpä pienin solmuerillinen polkupeite syntyy muodostamalla
|
|
|
|
|
polut kyseisten kaarten avulla.
|
|
|
|
|
|
|
|
|
|
Pienimmän polkupeitteen koko on $n-c$, jossa $n$ on verkon
|
|
|
|
|
solmujen määrä ja $c$ on maksimiparituksen kaarten määrä.
|
|
|
|
|
Esimerkiksi yllä olevassa verkossa pienimmän
|
|
|
|
|
polkupeitteen koko on $7-4=3$.
|
|
|
|
|
|
|
|
|
|
\subsubsection{Yleinen peite}
|
|
|
|
|
|
|
|
|
|
Yleisessä polkupeitteessä sama solmu voi kuulua moneen polkuun,
|
|
|
|
|
minkä ansiosta tarvittava polkujen määrä saattaa olla pienempi.
|
|
|
|
|
Esimerkkiverkossa pienin yleinen polkupeite muodostuu
|
|
|
|
|
kahdesta polusta seuraavasti:
|
|
|
|
|
|
|
|
|
|
\begin{center}
|
|
|
|
|
\begin{tikzpicture}[scale=0.9]
|
|
|
|
|
\node[draw, circle] (1) at (0,0) {1};
|
|
|
|
|
\node[draw, circle] (2) at (2,0) {2};
|
|
|
|
|
\node[draw, circle] (3) at (4,0) {3};
|
|
|
|
|
\node[draw, circle] (4) at (6,0) {4};
|
|
|
|
|
\node[draw, circle] (5) at (0,-2) {5};
|
|
|
|
|
\node[draw, circle] (6) at (2,-2) {6};
|
|
|
|
|
\node[draw, circle] (7) at (4,-2) {7};
|
|
|
|
|
|
|
|
|
|
\path[draw=blue,thick,->,line width=2pt] (1) -- (5);
|
|
|
|
|
\path[draw=blue,thick,->,line width=2pt] (5) -- (6);
|
|
|
|
|
\path[draw=blue,thick,->,line width=2pt] (6) -- (3);
|
|
|
|
|
\path[draw=blue,thick,->,line width=2pt] (3) -- (4);
|
|
|
|
|
\path[draw=green,thick,->,line width=2pt] (2) -- (6);
|
|
|
|
|
\path[draw=green,thick,->,line width=2pt] (6) -- (7);
|
|
|
|
|
\end{tikzpicture}
|
|
|
|
|
\end{center}
|
|
|
|
|
|
|
|
|
|
Tässä verkossä yleisessä polkupeitteessä on 2 polkua,
|
|
|
|
|
kun taas solmuerillisessä polkupeitteessä on 3 polkua.
|
|
|
|
|
Erona on, että yleisessä polkupeitteessä solmua 6
|
|
|
|
|
käytetään kahdessa polussa.
|
|
|
|
|
|
|
|
|
|
Yleisen polkupeitteen voi löytää lähes samalla
|
|
|
|
|
tavalla kuin solmuerillisen polkupeitteen.
|
|
|
|
|
Riittää täydentää maksimiparituksen verkkoa niin,
|
|
|
|
|
että siinä on kaari $a \rightarrow b$ aina silloin,
|
|
|
|
|
kun alkuperäisessä verkossa solmusta $a$ pääsee
|
|
|
|
|
solmuun $b$ (mahdollisesti usean kaaren kautta).
|
|
|
|
|
|
|
|
|
|
Nyt esimerkkiverkossa on seuraava tilanne:
|
|
|
|
|
\begin{center}
|
|
|
|
|
\begin{tikzpicture}[scale=0.9]
|
|
|
|
|
\node[draw, circle] (1a) at (0,6) {1};
|
|
|
|
|
\node[draw, circle] (2a) at (0,5) {2};
|
|
|
|
|
\node[draw, circle] (3a) at (0,4) {3};
|
|
|
|
|
\node[draw, circle] (4a) at (0,3) {4};
|
|
|
|
|
\node[draw, circle] (5a) at (0,2) {5};
|
|
|
|
|
\node[draw, circle] (6a) at (0,1) {6};
|
|
|
|
|
\node[draw, circle] (7a) at (0,0) {7};
|
|
|
|
|
|
|
|
|
|
\node[draw, circle] (1b) at (4,6) {1};
|
|
|
|
|
\node[draw, circle] (2b) at (4,5) {2};
|
|
|
|
|
\node[draw, circle] (3b) at (4,4) {3};
|
|
|
|
|
\node[draw, circle] (4b) at (4,3) {4};
|
|
|
|
|
\node[draw, circle] (5b) at (4,2) {5};
|
|
|
|
|
\node[draw, circle] (6b) at (4,1) {6};
|
|
|
|
|
\node[draw, circle] (7b) at (4,0) {7};
|
|
|
|
|
|
|
|
|
|
\node[draw, circle] (a) at (-3,3) {\phantom{0}};
|
|
|
|
|
\node[draw, circle] (b) at (7,3) {\phantom{0}};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
%\path[draw,thick,->,>=latex] (1a) -- (5b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (1a) -- (6b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (1a) -- (7b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (1a) -- (3b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (1a) -- (4b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (5a) -- (6b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (5a) -- (7b);
|
|
|
|
|
%\path[draw,thick,->,>=latex] (5a) -- (3b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (5a) -- (4b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (6a) -- (7b);
|
|
|
|
|
%\path[draw,thick,->,>=latex] (6a) -- (7b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (6a) -- (3b);
|
|
|
|
|
%\path[draw,thick,->,>=latex] (3a) -- (4b);
|
|
|
|
|
%\path[draw,thick,->,>=latex] (2a) -- (6b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (2a) -- (7b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (2a) -- (3b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (2a) -- (4b);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\path[draw,thick,->,>=latex] (a) -- (1a);
|
|
|
|
|
\path[draw,thick,->,>=latex] (a) -- (2a);
|
|
|
|
|
\path[draw,thick,->,>=latex] (a) -- (3a);
|
|
|
|
|
\path[draw,thick,->,>=latex] (a) -- (4a);
|
|
|
|
|
\path[draw,thick,->,>=latex] (a) -- (5a);
|
|
|
|
|
\path[draw,thick,->,>=latex] (a) -- (6a);
|
|
|
|
|
\path[draw,thick,->,>=latex] (a) -- (7a);
|
|
|
|
|
|
|
|
|
|
\path[draw,thick,->,>=latex] (1b) -- (b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (2b) -- (b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (3b) -- (b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (4b) -- (b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (5b) -- (b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (6b) -- (b);
|
|
|
|
|
\path[draw,thick,->,>=latex] (7b) -- (b);
|
|
|
|
|
|
|
|
|
|
\path[draw=red,thick,->,line width=2pt] (1a) -- (5b);
|
|
|
|
|
\path[draw=red,thick,->,line width=2pt] (5a) -- (3b);
|
|
|
|
|
\path[draw=red,thick,->,line width=2pt] (3a) -- (4b);
|
|
|
|
|
\path[draw=red,thick,->,line width=2pt] (2a) -- (6b);
|
|
|
|
|
\path[draw=red,thick,->,line width=2pt] (6a) -- (7b);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
% \path[draw=red,thick,->,line width=2pt] (1a) -- (6b);
|
|
|
|
|
% \path[draw=red,thick,->,line width=2pt] (1a) -- (7b);
|
|
|
|
|
% \path[draw=red,thick,->,line width=2pt] (1a) -- (3b);
|
|
|
|
|
% \path[draw=red,thick,->,line width=2pt] (1a) -- (4b);
|
|
|
|
|
% \path[draw=red,thick,->,line width=2pt] (5a) -- (6b);
|
|
|
|
|
% \path[draw=red,thick,->,line width=2pt] (5a) -- (7b);
|
|
|
|
|
% \path[draw=red,thick,->,line width=2pt] (5a) -- (3b);
|
|
|
|
|
% \path[draw=red,thick,->,line width=2pt] (5a) -- (4b);
|
|
|
|
|
% \path[draw=red,thick,->,line width=2pt] (6a) -- (7b);
|
|
|
|
|
% \path[draw=red,thick,->,line width=2pt] (6a) -- (7b);
|
|
|
|
|
% \path[draw=red,thick,->,line width=2pt] (6a) -- (3b);
|
|
|
|
|
% \path[draw=red,thick,->,line width=2pt] (3a) -- (4b);
|
|
|
|
|
% \path[draw=red,thick,->,line width=2pt] (2a) -- (6b);
|
|
|
|
|
% \path[draw=red,thick,->,line width=2pt] (2a) -- (7b);
|
|
|
|
|
% \path[draw=red,thick,->,line width=2pt] (2a) -- (3b);
|
|
|
|
|
% \path[draw=red,thick,->,line width=2pt] (2a) -- (4b);
|
|
|
|
|
|
|
|
|
|
\end{tikzpicture}
|
|
|
|
|
\end{center}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\subsubsection{Dilworthin lause}
|
|
|
|
|
|
|
|
|
|
\index{Dilworthin lause@Dilworthin lause}
|
|
|
|
|
\index{antiketju@antiketju}
|
|
|
|
|
|
|
|
|
|
\key{Dilworthin lauseen} mukaan suunnatun, syklittömän
|
|
|
|
|
verkon pienin yleinen polkupeite
|
|
|
|
|
on yhtä suuri kuin suurin verkossa oleva \key{antiketju}
|
|
|
|
|
eli kokoelma solmuja,
|
|
|
|
|
jossa minkään kahden solmun välillä ei ole polkua.
|
|
|
|
|
|
|
|
|
|
Esimerkiksi äskeisessä verkossa pienin
|
|
|
|
|
yleinen polkupeite sisältää kaksi polkua,
|
|
|
|
|
joten verkon suurimmassa antiketjussa on kaksi solmua.
|
|
|
|
|
Tällainen antiketju muodostuu esimerkiksi
|
|
|
|
|
valitsemalla solmut 3 ja 7:
|
|
|
|
|
|
|
|
|
|
\begin{center}
|
|
|
|
|
\begin{tikzpicture}[scale=0.9]
|
|
|
|
|
\node[draw, circle] (1) at (0,0) {1};
|
|
|
|
|
\node[draw, circle] (2) at (2,0) {2};
|
|
|
|
|
\node[draw, circle, fill=lightgray] (3) at (4,0) {3};
|
|
|
|
|
\node[draw, circle] (4) at (6,0) {4};
|
|
|
|
|
\node[draw, circle] (5) at (0,-2) {5};
|
|
|
|
|
\node[draw, circle] (6) at (2,-2) {6};
|
|
|
|
|
\node[draw, circle, fill=lightgray] (7) at (4,-2) {7};
|
|
|
|
|
|
|
|
|
|
\path[draw,thick,->,>=latex] (1) -- (5);
|
|
|
|
|
\path[draw,thick,->,>=latex] (2) -- (6);
|
|
|
|
|
\path[draw,thick,->,>=latex] (3) -- (4);
|
|
|
|
|
\path[draw,thick,->,>=latex] (5) -- (6);
|
|
|
|
|
\path[draw,thick,->,>=latex] (6) -- (3);
|
|
|
|
|
\path[draw,thick,->,>=latex] (6) -- (7);
|
|
|
|
|
\end{tikzpicture}
|
|
|
|
|
\end{center}
|
|
|
|
|
|
|
|
|
|
Verkossa ei ole polkua solmusta 3 solmuun 7
|
|
|
|
|
eikä polkua solmusta 7 solmuun 3,
|
|
|
|
|
joten valinta on kelvollinen.
|
|
|
|
|
Toisaalta jos verkosta valitaan mitkä tahansa
|
|
|
|
|
kolme solmua, jostain solmusta toiseen on polku.
|
|
|
|
|
|