Corrections
This commit is contained in:
parent
f478d7044c
commit
c447a6f33b
127
luku11.tex
127
luku11.tex
|
@ -1,12 +1,12 @@
|
||||||
\chapter{Basics of graphs}
|
\chapter{Basics of graphs}
|
||||||
|
|
||||||
Many programming problems can be solved by
|
Many programming problems can be solved by
|
||||||
modelling the problem as a graph problem
|
modeling the problem as a graph problem
|
||||||
and using an appropriate graph algorithm.
|
and using an appropriate graph algorithm.
|
||||||
A typical example of a graph is a network
|
A typical example of a graph is a network
|
||||||
of roads and cities in a country.
|
of roads and cities in a country.
|
||||||
Sometimes, though, the graph is hidden
|
Sometimes, though, the graph is hidden
|
||||||
in the problem and it can be difficult to detect it.
|
in the problem and it may be difficult to detect it.
|
||||||
|
|
||||||
This part of the book discusses graph algorithms,
|
This part of the book discusses graph algorithms,
|
||||||
especially focusing on topics that
|
especially focusing on topics that
|
||||||
|
@ -15,7 +15,7 @@ In this chapter, we go through concepts
|
||||||
related to graphs,
|
related to graphs,
|
||||||
and study different ways to represent graphs in algorithms.
|
and study different ways to represent graphs in algorithms.
|
||||||
|
|
||||||
\section{Terminology}
|
\section{Graph terminology}
|
||||||
|
|
||||||
\index{graph}
|
\index{graph}
|
||||||
\index{node}
|
\index{node}
|
||||||
|
@ -56,17 +56,51 @@ A \key{path} leads from node $a$ to node $b$
|
||||||
through edges of the graph.
|
through edges of the graph.
|
||||||
The \key{length} of a path is the number of
|
The \key{length} of a path is the number of
|
||||||
edges in it.
|
edges in it.
|
||||||
For example, in the above graph, there
|
For example, the above graph contains
|
||||||
are several paths from node 1 to node 5:
|
the path $1 \rightarrow 3 \rightarrow 4 \rightarrow 5$
|
||||||
|
from node 1 to node 5:
|
||||||
|
|
||||||
\begin{itemize}
|
\begin{center}
|
||||||
\item $1 \rightarrow 2 \rightarrow 5$ (length 2)
|
\begin{tikzpicture}[scale=0.9]
|
||||||
\item $1 \rightarrow 4 \rightarrow 5$ (length 2)
|
\node[draw, circle] (1) at (1,3) {$1$};
|
||||||
\item $1 \rightarrow 2 \rightarrow 4 \rightarrow 5$ (length 3)
|
\node[draw, circle] (2) at (4,3) {$2$};
|
||||||
\item $1 \rightarrow 3 \rightarrow 4 \rightarrow 5$ (length 3)
|
\node[draw, circle] (3) at (1,1) {$3$};
|
||||||
\item $1 \rightarrow 4 \rightarrow 2 \rightarrow 5$ (length 3)
|
\node[draw, circle] (4) at (4,1) {$4$};
|
||||||
\item $1 \rightarrow 3 \rightarrow 4 \rightarrow 2 \rightarrow 5$ (length 4)
|
\node[draw, circle] (5) at (6,2) {$5$};
|
||||||
\end{itemize}
|
|
||||||
|
\path[draw,thick,-] (1) -- (2);
|
||||||
|
\path[draw,thick,-] (1) -- (3);
|
||||||
|
\path[draw,thick,-] (1) -- (4);
|
||||||
|
\path[draw,thick,-] (3) -- (4);
|
||||||
|
\path[draw,thick,-] (2) -- (4);
|
||||||
|
\path[draw,thick,-] (2) -- (5);
|
||||||
|
\path[draw,thick,-] (4) -- (5);
|
||||||
|
|
||||||
|
\path[draw=red,thick,->,line width=2pt] (1) -- (3);
|
||||||
|
\path[draw=red,thick,->,line width=2pt] (3) -- (4);
|
||||||
|
\path[draw=red,thick,->,line width=2pt] (4) -- (5);
|
||||||
|
\end{tikzpicture}
|
||||||
|
\end{center}
|
||||||
|
|
||||||
|
\index{cycle}
|
||||||
|
|
||||||
|
A path is a \key{cycle} if the first and last
|
||||||
|
node is the same.
|
||||||
|
For example, the above graph contains
|
||||||
|
the cycle $1 \rightarrow 3 \rightarrow 4 \rightarrow 1$.
|
||||||
|
A path is \key{simple} if each node appears
|
||||||
|
at most once in the path.
|
||||||
|
|
||||||
|
|
||||||
|
%
|
||||||
|
% \begin{itemize}
|
||||||
|
% \item $1 \rightarrow 2 \rightarrow 5$ (length 2)
|
||||||
|
% \item $1 \rightarrow 4 \rightarrow 5$ (length 2)
|
||||||
|
% \item $1 \rightarrow 2 \rightarrow 4 \rightarrow 5$ (length 3)
|
||||||
|
% \item $1 \rightarrow 3 \rightarrow 4 \rightarrow 5$ (length 3)
|
||||||
|
% \item $1 \rightarrow 4 \rightarrow 2 \rightarrow 5$ (length 3)
|
||||||
|
% \item $1 \rightarrow 3 \rightarrow 4 \rightarrow 2 \rightarrow 5$ (length 4)
|
||||||
|
% \end{itemize}
|
||||||
|
|
||||||
\subsubsection{Connectivity}
|
\subsubsection{Connectivity}
|
||||||
|
|
||||||
|
@ -185,29 +219,18 @@ For example, the following graph is directed:
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
The above graph contains a path from
|
The above graph contains
|
||||||
node $3$ to node $5$ through the edges
|
the path $3 \rightarrow 1 \rightarrow 2 \rightarrow 5$
|
||||||
$3 \rightarrow 1 \rightarrow 2 \rightarrow 5$,
|
from node $3$ to node $5$,
|
||||||
but there is no path from node $5$ to node $3$.
|
but there is no path from node $5$ to node $3$.
|
||||||
|
|
||||||
\index{cycle}
|
|
||||||
\index{acyclic graph}
|
|
||||||
|
|
||||||
A \key{cycle} is a path whose first and
|
|
||||||
last node is the same.
|
|
||||||
For example, the above graph contains
|
|
||||||
a cycle
|
|
||||||
$1 \rightarrow 2 \rightarrow 4 \rightarrow 1$.
|
|
||||||
If a graph does not contain any cycles,
|
|
||||||
it is called \key{acyclic}.
|
|
||||||
|
|
||||||
\subsubsection{Edge weights}
|
\subsubsection{Edge weights}
|
||||||
|
|
||||||
\index{weighted graph}
|
\index{weighted graph}
|
||||||
|
|
||||||
In a \key{weighted} graph, each edge is assigned
|
In a \key{weighted} graph, each edge is assigned
|
||||||
a \key{weight}.
|
a \key{weight}.
|
||||||
Often, the weights are interpreted as edge lengths.
|
Often the weights are interpreted as edge lengths.
|
||||||
For example, the following graph is weighted:
|
For example, the following graph is weighted:
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.9]
|
\begin{tikzpicture}[scale=0.9]
|
||||||
|
@ -268,7 +291,7 @@ so its degree is 3.
|
||||||
The sum of degrees in a graph is always $2m$,
|
The sum of degrees in a graph is always $2m$,
|
||||||
where $m$ is the number of edges,
|
where $m$ is the number of edges,
|
||||||
because each edge
|
because each edge
|
||||||
increases the degree of two nodes by one.
|
increases the degree of exactly two nodes by one.
|
||||||
For this reason, the sum of degrees is always even.
|
For this reason, the sum of degrees is always even.
|
||||||
|
|
||||||
\index{regular graph}
|
\index{regular graph}
|
||||||
|
@ -358,7 +381,7 @@ is bipartite, because it can be colored as follows:
|
||||||
\path[draw,thick,-] (5) -- (6);
|
\path[draw,thick,-] (5) -- (6);
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
However, the following graph is not bipartite:
|
However, the graph
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.9]
|
\begin{tikzpicture}[scale=0.9]
|
||||||
\node[draw, circle] (1) at (1,3) {$2$};
|
\node[draw, circle] (1) at (1,3) {$2$};
|
||||||
|
@ -376,6 +399,29 @@ However, the following graph is not bipartite:
|
||||||
\path[draw,thick,-] (1) -- (6);
|
\path[draw,thick,-] (1) -- (6);
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
is not bipartite, because it is not possible to color
|
||||||
|
the following cycle of three nodes using two colors:
|
||||||
|
\begin{center}
|
||||||
|
\begin{tikzpicture}[scale=0.9]
|
||||||
|
\node[draw, circle] (1) at (1,3) {$2$};
|
||||||
|
\node[draw, circle] (2) at (4,3) {$3$};
|
||||||
|
\node[draw, circle] (3) at (1,1) {$5$};
|
||||||
|
\node[draw, circle] (4) at (4,1) {$6$};
|
||||||
|
\node[draw, circle] (5) at (-2,1) {$4$};
|
||||||
|
\node[draw, circle] (6) at (-2,3) {$1$};
|
||||||
|
\path[draw,thick,-] (1) -- (2);
|
||||||
|
\path[draw,thick,-] (1) -- (3);
|
||||||
|
\path[draw,thick,-] (3) -- (4);
|
||||||
|
\path[draw,thick,-] (2) -- (4);
|
||||||
|
\path[draw,thick,-] (3) -- (6);
|
||||||
|
\path[draw,thick,-] (5) -- (6);
|
||||||
|
\path[draw,thick,-] (1) -- (6);
|
||||||
|
|
||||||
|
\path[draw=red,thick,-,line width=2pt] (1) -- (3);
|
||||||
|
\path[draw=red,thick,-,line width=2pt] (3) -- (6);
|
||||||
|
\path[draw=red,thick,-,line width=2pt] (6) -- (1);
|
||||||
|
\end{tikzpicture}
|
||||||
|
\end{center}
|
||||||
|
|
||||||
\subsubsection{Simplicity}
|
\subsubsection{Simplicity}
|
||||||
|
|
||||||
|
@ -386,7 +432,7 @@ if no edge starts and ends at the same node,
|
||||||
and there are no multiple
|
and there are no multiple
|
||||||
edges between two nodes.
|
edges between two nodes.
|
||||||
Often we assume that graphs are simple.
|
Often we assume that graphs are simple.
|
||||||
For example, the graph
|
For example, the following graph is \emph{not} simple:
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.9]
|
\begin{tikzpicture}[scale=0.9]
|
||||||
\node[draw, circle] (1) at (1,3) {$2$};
|
\node[draw, circle] (1) at (1,3) {$2$};
|
||||||
|
@ -409,9 +455,6 @@ For example, the graph
|
||||||
\path[draw,thick,-] (5) edge [loop left] (5);
|
\path[draw,thick,-] (5) edge [loop left] (5);
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
is \emph{not} simple, because there is an edge that starts
|
|
||||||
and ends at node 4, and there are two edges
|
|
||||||
between nodes 2 and 3.
|
|
||||||
|
|
||||||
\section{Graph representation}
|
\section{Graph representation}
|
||||||
|
|
||||||
|
@ -420,7 +463,7 @@ in algorithms.
|
||||||
The choice of a data structure
|
The choice of a data structure
|
||||||
depends on the size of the graph and
|
depends on the size of the graph and
|
||||||
the way the algorithm processes it.
|
the way the algorithm processes it.
|
||||||
Next we will go through three possible representations.
|
Next we will go through three common representations.
|
||||||
|
|
||||||
\subsubsection{Adjacency list representation}
|
\subsubsection{Adjacency list representation}
|
||||||
|
|
||||||
|
@ -431,7 +474,7 @@ each node $x$ in the graph is assigned an \key{adjacency list}
|
||||||
that consists of nodes
|
that consists of nodes
|
||||||
to which there is an edge from $x$.
|
to which there is an edge from $x$.
|
||||||
Adjacency lists are the most popular
|
Adjacency lists are the most popular
|
||||||
way to represent a graph, and most algorithms can be
|
way to represent graphs, and most algorithms can be
|
||||||
efficiently implemented using them.
|
efficiently implemented using them.
|
||||||
|
|
||||||
A convenient way to store the adjacency lists is to declare
|
A convenient way to store the adjacency lists is to declare
|
||||||
|
@ -440,8 +483,8 @@ an array of vectors as follows:
|
||||||
vector<int> v[N];
|
vector<int> v[N];
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
The constant $N$ is chosen so that there
|
The constant $N$ is chosen so that all
|
||||||
is space for all adjacency lists.
|
adjacency lists can be stored.
|
||||||
For example, the graph
|
For example, the graph
|
||||||
|
|
||||||
\begin{center}
|
\begin{center}
|
||||||
|
@ -468,7 +511,7 @@ v[4].push_back(1);
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
If the graph is undirected, it can be stored in a similar way,
|
If the graph is undirected, it can be stored in a similar way,
|
||||||
but each edge is stored in both directions.
|
but each edge is added in both directions.
|
||||||
|
|
||||||
For a weighted graph, the structure can be extended
|
For a weighted graph, the structure can be extended
|
||||||
as follows:
|
as follows:
|
||||||
|
@ -507,7 +550,7 @@ v[4].push_back({1,2});
|
||||||
|
|
||||||
The benefit in using adjacency lists is that
|
The benefit in using adjacency lists is that
|
||||||
we can efficiently find the nodes to which
|
we can efficiently find the nodes to which
|
||||||
we can move from a certain node through an edge.
|
we can move from a given node through an edge.
|
||||||
For example, the following loop goes through all nodes
|
For example, the following loop goes through all nodes
|
||||||
to which we can move from node $s$:
|
to which we can move from node $s$:
|
||||||
|
|
||||||
|
@ -522,7 +565,7 @@ for (auto u : v[s]) {
|
||||||
\index{adjacency matrix}
|
\index{adjacency matrix}
|
||||||
|
|
||||||
An \key{adjacency matrix} is a two-dimensional array
|
An \key{adjacency matrix} is a two-dimensional array
|
||||||
that indicates which edges exist in the graph.
|
that indicates which edges the graph contains.
|
||||||
We can efficiently check from an adjacency matrix
|
We can efficiently check from an adjacency matrix
|
||||||
if there is an edge between two nodes.
|
if there is an edge between two nodes.
|
||||||
The matrix can be stored as an array
|
The matrix can be stored as an array
|
||||||
|
@ -647,7 +690,7 @@ if the graph is large.
|
||||||
An \key{edge list} contains all edges of a graph
|
An \key{edge list} contains all edges of a graph
|
||||||
in some order.
|
in some order.
|
||||||
This is a convenient way to represent a graph
|
This is a convenient way to represent a graph
|
||||||
if the algorithm processes all edges of the graph,
|
if the algorithm processes all edges of the graph
|
||||||
and it is not needed to find edges that start
|
and it is not needed to find edges that start
|
||||||
at a given node.
|
at a given node.
|
||||||
|
|
||||||
|
|
40
luku12.tex
40
luku12.tex
|
@ -48,9 +48,8 @@ the following graph:
|
||||||
\path[draw,thick,-] (2) -- (5);
|
\path[draw,thick,-] (2) -- (5);
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
The algorithm can begin at any node in the graph,
|
We may begin the search at any node in the graph,
|
||||||
but we will now assume that it begins
|
but we will now begin the search at node 1.
|
||||||
at node 1.
|
|
||||||
|
|
||||||
The search first proceeds to node 2:
|
The search first proceeds to node 2:
|
||||||
\begin{center}
|
\begin{center}
|
||||||
|
@ -305,7 +304,7 @@ to implement than depth-first search,
|
||||||
because the algorithm visits nodes
|
because the algorithm visits nodes
|
||||||
in different parts of the graph.
|
in different parts of the graph.
|
||||||
A typical implementation is based on
|
A typical implementation is based on
|
||||||
a queue of nodes to be processed.
|
a queue that contains nodes.
|
||||||
At each step, the next node in the queue
|
At each step, the next node in the queue
|
||||||
will be processed.
|
will be processed.
|
||||||
|
|
||||||
|
@ -329,7 +328,7 @@ int z[N], e[N];
|
||||||
so that the array \texttt{z} indicates
|
so that the array \texttt{z} indicates
|
||||||
which nodes the search has already visited
|
which nodes the search has already visited
|
||||||
and the array \texttt{e} will contain the
|
and the array \texttt{e} will contain the
|
||||||
minimum distance to all nodes in the graph.
|
distances to all nodes in the graph.
|
||||||
The search can be implemented as follows:
|
The search can be implemented as follows:
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
z[s] = 1; e[x] = 0;
|
z[s] = 1; e[x] = 0;
|
||||||
|
@ -364,7 +363,7 @@ assume that the graph is undirected.
|
||||||
A graph is connected if there is a path
|
A graph is connected if there is a path
|
||||||
between any two nodes in the graph.
|
between any two nodes in the graph.
|
||||||
Thus, we can check if a graph is connected
|
Thus, we can check if a graph is connected
|
||||||
by selecting an arbitrary node and
|
by choosing an arbitrary node and
|
||||||
finding out if we can reach all other nodes.
|
finding out if we can reach all other nodes.
|
||||||
|
|
||||||
For example, in the graph
|
For example, in the graph
|
||||||
|
@ -406,7 +405,7 @@ the following nodes:
|
||||||
Since the search did not visit all the nodes,
|
Since the search did not visit all the nodes,
|
||||||
we can conclude that the graph is not connected.
|
we can conclude that the graph is not connected.
|
||||||
In a similar way, we can also find all connected components
|
In a similar way, we can also find all connected components
|
||||||
of a graph by iterating trough the nodes and always
|
of a graph by iterating through the nodes and always
|
||||||
starting a new depth-first search if the current node
|
starting a new depth-first search if the current node
|
||||||
does not belong to any component yet.
|
does not belong to any component yet.
|
||||||
|
|
||||||
|
@ -421,6 +420,24 @@ visited.
|
||||||
For example, the graph
|
For example, the graph
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}
|
\begin{tikzpicture}
|
||||||
|
\node[draw, circle] (2) at (7,5) {$2$};
|
||||||
|
\node[draw, circle] (1) at (3,5) {$1$};
|
||||||
|
\node[draw, circle] (3) at (5,4) {$3$};
|
||||||
|
\node[draw, circle] (5) at (7,3) {$5$};
|
||||||
|
\node[draw, circle] (4) at (3,3) {$4$};
|
||||||
|
|
||||||
|
\path[draw,thick,-] (1) -- (3);
|
||||||
|
\path[draw,thick,-] (1) -- (4);
|
||||||
|
\path[draw,thick,-] (3) -- (4);
|
||||||
|
\path[draw,thick,-] (2) -- (5);
|
||||||
|
\path[draw,thick,-] (2) -- (3);
|
||||||
|
\path[draw,thick,-] (3) -- (5);
|
||||||
|
\end{tikzpicture}
|
||||||
|
\end{center}
|
||||||
|
contains two cycles and we can find one
|
||||||
|
of them as follows:
|
||||||
|
\begin{center}
|
||||||
|
\begin{tikzpicture}
|
||||||
\node[draw, circle,fill=lightgray] (2) at (7,5) {$2$};
|
\node[draw, circle,fill=lightgray] (2) at (7,5) {$2$};
|
||||||
\node[draw, circle,fill=lightgray] (1) at (3,5) {$1$};
|
\node[draw, circle,fill=lightgray] (1) at (3,5) {$1$};
|
||||||
\node[draw, circle,fill=lightgray] (3) at (5,4) {$3$};
|
\node[draw, circle,fill=lightgray] (3) at (5,4) {$3$};
|
||||||
|
@ -440,7 +457,7 @@ For example, the graph
|
||||||
|
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
contains a cycle because when we move from
|
When we move from
|
||||||
node 2 to node 5 it turns out
|
node 2 to node 5 it turns out
|
||||||
that the neighbor 3 has already been visited.
|
that the neighbor 3 has already been visited.
|
||||||
Thus, the graph contains a cycle that goes through node 3,
|
Thus, the graph contains a cycle that goes through node 3,
|
||||||
|
@ -450,7 +467,8 @@ Another way to find out whether a graph contains a cycle
|
||||||
is to simply calculate the number of nodes and edges
|
is to simply calculate the number of nodes and edges
|
||||||
in every component.
|
in every component.
|
||||||
If a component contains $c$ nodes and no cycle,
|
If a component contains $c$ nodes and no cycle,
|
||||||
it must contain exactly $c-1$ edges.
|
it must contain exactly $c-1$ edges
|
||||||
|
(so it has to be a tree).
|
||||||
If there are $c$ or more edges, the component
|
If there are $c$ or more edges, the component
|
||||||
surely contains a cycle.
|
surely contains a cycle.
|
||||||
|
|
||||||
|
@ -489,7 +507,7 @@ For example, the graph
|
||||||
\path[draw,thick,-] (5) -- (3);
|
\path[draw,thick,-] (5) -- (3);
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
is not bipartite because a search from node 1
|
is not bipartite, because a search from node 1
|
||||||
proceeds as follows:
|
proceeds as follows:
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}
|
\begin{tikzpicture}
|
||||||
|
@ -512,7 +530,7 @@ proceeds as follows:
|
||||||
\path[draw=red,thick,->,line width=2pt] (5) -- (2);
|
\path[draw=red,thick,->,line width=2pt] (5) -- (2);
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
We notice that the color or both node 2 and node 5
|
We notice that the color or both nodes 2 and 5
|
||||||
is red, while they are adjacent nodes in the graph.
|
is red, while they are adjacent nodes in the graph.
|
||||||
Thus, the graph is not bipartite.
|
Thus, the graph is not bipartite.
|
||||||
|
|
||||||
|
|
72
luku13.tex
72
luku13.tex
|
@ -7,7 +7,7 @@ of a graph
|
||||||
is an important problem that has many
|
is an important problem that has many
|
||||||
applications in practice.
|
applications in practice.
|
||||||
For example, a natural problem in a road network
|
For example, a natural problem in a road network
|
||||||
is to calculate the length of the shorthest route
|
is to calculate the length of the shortest route
|
||||||
between two cities, given the lengths of the roads.
|
between two cities, given the lengths of the roads.
|
||||||
|
|
||||||
In an unweighted graph, the length of a path equals
|
In an unweighted graph, the length of a path equals
|
||||||
|
@ -15,8 +15,8 @@ the number of edges in the path and we can
|
||||||
simply use breadth-first search to find
|
simply use breadth-first search to find
|
||||||
the shortest path.
|
the shortest path.
|
||||||
However, in this chapter we concentrate on
|
However, in this chapter we concentrate on
|
||||||
weighted graphs,
|
weighted graphs
|
||||||
and more sophisticated algorithms
|
where more sophisticated algorithms
|
||||||
are needed
|
are needed
|
||||||
for finding shortest paths.
|
for finding shortest paths.
|
||||||
|
|
||||||
|
@ -70,9 +70,8 @@ Each node in the graph is assigned a distance.
|
||||||
Initially, the distance to the starting node is 0,
|
Initially, the distance to the starting node is 0,
|
||||||
and the distance to all other nodes is infinite.
|
and the distance to all other nodes is infinite.
|
||||||
|
|
||||||
The algorithm searches for edges that reduce the
|
The algorithm searches for edges that reduce distances.
|
||||||
distances.
|
First, all edges from node 1 reduce distances:
|
||||||
First, all edges from node 1 reduce the distances:
|
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}
|
\begin{tikzpicture}
|
||||||
\node[draw, circle] (1) at (1,3) {1};
|
\node[draw, circle] (1) at (1,3) {1};
|
||||||
|
@ -100,7 +99,7 @@ First, all edges from node 1 reduce the distances:
|
||||||
\end{center}
|
\end{center}
|
||||||
After this, edges
|
After this, edges
|
||||||
$2 \rightarrow 5$ and $3 \rightarrow 4$
|
$2 \rightarrow 5$ and $3 \rightarrow 4$
|
||||||
reduce the distances:
|
reduce distances:
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}
|
\begin{tikzpicture}
|
||||||
\node[draw, circle] (1) at (1,3) {1};
|
\node[draw, circle] (1) at (1,3) {1};
|
||||||
|
@ -156,7 +155,7 @@ and we have successfully
|
||||||
calculated the shortest distance
|
calculated the shortest distance
|
||||||
from the starting node to all other nodes.
|
from the starting node to all other nodes.
|
||||||
|
|
||||||
For example, the smallest distance 3
|
For example, the shortest distance 3
|
||||||
from node 1 to node 5 corresponds to
|
from node 1 to node 5 corresponds to
|
||||||
the following path:
|
the following path:
|
||||||
|
|
||||||
|
@ -201,9 +200,9 @@ there is an edge to node $x$ with weight $w$.
|
||||||
|
|
||||||
The algorithm consists of $n-1$ rounds,
|
The algorithm consists of $n-1$ rounds,
|
||||||
and on each round the algorithm goes through
|
and on each round the algorithm goes through
|
||||||
all edges in the graph and tries to
|
all edges of the graph and tries to
|
||||||
reduce the distances.
|
reduce the distances.
|
||||||
The algorithm builds an array \texttt{e}
|
The algorithm constructs an array \texttt{e}
|
||||||
that will contain the distance from $x$
|
that will contain the distance from $x$
|
||||||
to all nodes in the graph.
|
to all nodes in the graph.
|
||||||
The initial value $10^9$ means infinity.
|
The initial value $10^9$ means infinity.
|
||||||
|
@ -228,7 +227,7 @@ all distances are final after $n-1$ rounds,
|
||||||
because each shortest path can contain at most $n-1$ edges.
|
because each shortest path can contain at most $n-1$ edges.
|
||||||
|
|
||||||
In practice, the final distances can usually
|
In practice, the final distances can usually
|
||||||
be found much faster than in $n-1$ rounds.
|
be found faster than in $n-1$ rounds.
|
||||||
Thus, a possible way to make the algorithm more efficient
|
Thus, a possible way to make the algorithm more efficient
|
||||||
is to stop the algorithm if no distance
|
is to stop the algorithm if no distance
|
||||||
can be reduced during a round.
|
can be reduced during a round.
|
||||||
|
@ -272,7 +271,8 @@ using the Bellman–Ford algorithm by
|
||||||
running the algorithm for $n$ rounds.
|
running the algorithm for $n$ rounds.
|
||||||
If the last round reduces any distance,
|
If the last round reduces any distance,
|
||||||
the graph contains a negative cycle.
|
the graph contains a negative cycle.
|
||||||
Note that this algorithm searches for
|
Note that this algorithm can be used to
|
||||||
|
search for
|
||||||
a negative cycle in the whole graph
|
a negative cycle in the whole graph
|
||||||
regardless of the starting node.
|
regardless of the starting node.
|
||||||
|
|
||||||
|
@ -283,7 +283,7 @@ regardless of the starting node.
|
||||||
The \key{SPFA algorithm} (''Shortest Path Faster Algorithm'')
|
The \key{SPFA algorithm} (''Shortest Path Faster Algorithm'')
|
||||||
is a variant of the Bellman–Ford algorithm,
|
is a variant of the Bellman–Ford algorithm,
|
||||||
that is often more efficient than the original algorithm.
|
that is often more efficient than the original algorithm.
|
||||||
It does not go through all the edges on each round,
|
The SPFA algorithm does not go through all the edges on each round,
|
||||||
but instead, it chooses the edges to be examined
|
but instead, it chooses the edges to be examined
|
||||||
in a more intelligent way.
|
in a more intelligent way.
|
||||||
|
|
||||||
|
@ -294,11 +294,11 @@ to the queue.
|
||||||
Then, the algorithm always processes the
|
Then, the algorithm always processes the
|
||||||
first node in the queue, and when an edge
|
first node in the queue, and when an edge
|
||||||
$a \rightarrow b$ reduces a distance,
|
$a \rightarrow b$ reduces a distance,
|
||||||
node $b$ is added to the end of the queue.
|
node $b$ is added to the queue.
|
||||||
|
|
||||||
The following implementation uses a
|
The following implementation uses a
|
||||||
\texttt{queue} structure \texttt{q}.
|
\texttt{queue} \texttt{q}.
|
||||||
In addition, the array \texttt{z} indicates
|
In addition, an array \texttt{z} indicates
|
||||||
if a node is already in the queue,
|
if a node is already in the queue,
|
||||||
in which case the algorithm does not add
|
in which case the algorithm does not add
|
||||||
the node to the queue again.
|
the node to the queue again.
|
||||||
|
@ -321,11 +321,11 @@ while (!q.empty()) {
|
||||||
|
|
||||||
The efficiency of the SPFA algorithm depends
|
The efficiency of the SPFA algorithm depends
|
||||||
on the structure of the graph:
|
on the structure of the graph:
|
||||||
the algorithm is often very efficient,
|
the algorithm is often efficient,
|
||||||
but its worst case time complexity is still
|
but its worst case time complexity is still
|
||||||
$O(nm)$ and it is possible to create inputs
|
$O(nm)$ and it is possible to create inputs
|
||||||
that make the algorithm as slow as the
|
that make the algorithm as slow as the
|
||||||
standard Bellman–Ford algorithm.
|
original Bellman–Ford algorithm.
|
||||||
|
|
||||||
\section{Dijkstra's algorithm}
|
\section{Dijkstra's algorithm}
|
||||||
|
|
||||||
|
@ -342,7 +342,7 @@ are no negative weight edges in the graph.
|
||||||
|
|
||||||
Like the Bellman–Ford algorithm,
|
Like the Bellman–Ford algorithm,
|
||||||
Dijkstra's algorithm maintains distances
|
Dijkstra's algorithm maintains distances
|
||||||
for the nodes and reduces them during the algorithm.
|
to the nodes and reduces them during the search.
|
||||||
Dijkstra's algorithm is efficient, because
|
Dijkstra's algorithm is efficient, because
|
||||||
it only processes
|
it only processes
|
||||||
each edge in the graph once, using the fact
|
each edge in the graph once, using the fact
|
||||||
|
@ -376,7 +376,7 @@ starting node is node 1:
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
Like in the Bellman–Ford algorithm,
|
Like in the Bellman–Ford algorithm,
|
||||||
intially the distance to the starting node is 0
|
initially the distance to the starting node is 0
|
||||||
and the distance to all other nodes is infinite.
|
and the distance to all other nodes is infinite.
|
||||||
|
|
||||||
At each step, Dijkstra's algorithm selects a node
|
At each step, Dijkstra's algorithm selects a node
|
||||||
|
@ -529,7 +529,7 @@ However, Dijkstra's algorithm
|
||||||
finds the path $1 \rightarrow 2 \rightarrow 4$
|
finds the path $1 \rightarrow 2 \rightarrow 4$
|
||||||
by following the minimum weight edges.
|
by following the minimum weight edges.
|
||||||
The algorithm does not take into account that
|
The algorithm does not take into account that
|
||||||
on the lower path, the weight $-5$
|
on the other path, the weight $-5$
|
||||||
compensates the previous large weight $6$.
|
compensates the previous large weight $6$.
|
||||||
|
|
||||||
\subsubsection{Implementation}
|
\subsubsection{Implementation}
|
||||||
|
@ -550,7 +550,7 @@ can be retrieved in logarithmic time.
|
||||||
|
|
||||||
In the following implementation,
|
In the following implementation,
|
||||||
the priority queue contains pairs whose first
|
the priority queue contains pairs whose first
|
||||||
element is the current distance of the node and second
|
element is the current distance to the node and second
|
||||||
element is the identifier of the node.
|
element is the identifier of the node.
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
priority_queue<pair<int,int>> q;
|
priority_queue<pair<int,int>> q;
|
||||||
|
@ -559,12 +559,12 @@ A small difficulty is that in Dijkstra's algorithm,
|
||||||
we should find the node with the \emph{minimum} distance,
|
we should find the node with the \emph{minimum} distance,
|
||||||
while the C++ priority queue finds the \emph{maximum}
|
while the C++ priority queue finds the \emph{maximum}
|
||||||
element as default.
|
element as default.
|
||||||
An easy solution is to use \emph{negative} distances,
|
An easy trick is to use \emph{negative} distances,
|
||||||
which allows us to directly use the C++ priority queue.
|
which allows us to directly use the C++ priority queue.
|
||||||
|
|
||||||
The code keeps track of processed nodes
|
The code keeps track of processed nodes
|
||||||
in the array \texttt{z},
|
in an array \texttt{z},
|
||||||
and maintains estimated distances in array \texttt{e}.
|
and maintains the distances in an array \texttt{e}.
|
||||||
Initially, the distance to the starting node is 0,
|
Initially, the distance to the starting node is 0,
|
||||||
and the distance to all other nodes is $10^9$ (infinite).
|
and the distance to all other nodes is $10^9$ (infinite).
|
||||||
|
|
||||||
|
@ -587,8 +587,8 @@ while (!q.empty()) {
|
||||||
|
|
||||||
The time complexity of the above implementation is
|
The time complexity of the above implementation is
|
||||||
$O(n+m \log m)$ because the algorithm goes through
|
$O(n+m \log m)$ because the algorithm goes through
|
||||||
all nodes in the graph, and adds for each edge
|
all nodes in the graph and adds for each edge
|
||||||
at most one estimated distance to the priority queue.
|
at most one distance to the priority queue.
|
||||||
|
|
||||||
\section{Floyd–Warshall algorithm}
|
\section{Floyd–Warshall algorithm}
|
||||||
|
|
||||||
|
@ -605,7 +605,7 @@ The algorithm maintains a two-dimensional array
|
||||||
that contains distances between the nodes.
|
that contains distances between the nodes.
|
||||||
First, the distances are calculated only using
|
First, the distances are calculated only using
|
||||||
direct edges between the nodes.
|
direct edges between the nodes.
|
||||||
After this the algorithm updates the distances
|
After this the algorithm reduces the distances
|
||||||
by using intermediate nodes in the paths.
|
by using intermediate nodes in the paths.
|
||||||
|
|
||||||
\subsubsection{Example}
|
\subsubsection{Example}
|
||||||
|
@ -654,7 +654,7 @@ that can act as an intermediate node in paths from now on,
|
||||||
and the algorithm reduces the distances in the array
|
and the algorithm reduces the distances in the array
|
||||||
using this node.
|
using this node.
|
||||||
|
|
||||||
On the first round, node 1 is the intermediate node.
|
On the first round, node 1 is the new intermediate node.
|
||||||
There is a new path between nodes 2 and 4
|
There is a new path between nodes 2 and 4
|
||||||
with length 14, because node 1 connects them.
|
with length 14, because node 1 connects them.
|
||||||
There is also a new path
|
There is also a new path
|
||||||
|
@ -673,7 +673,7 @@ between nodes 2 and 5 with length 6.
|
||||||
\end{center}
|
\end{center}
|
||||||
\vspace{10pt}
|
\vspace{10pt}
|
||||||
|
|
||||||
On the second round, node 2 is the intermediate node.
|
On the second round, node 2 is the new intermediate node.
|
||||||
This creates new paths between nodes 1 and 3
|
This creates new paths between nodes 1 and 3
|
||||||
and between nodes 3 and 5:
|
and between nodes 3 and 5:
|
||||||
|
|
||||||
|
@ -690,7 +690,7 @@ and between nodes 3 and 5:
|
||||||
\end{center}
|
\end{center}
|
||||||
\vspace{10pt}
|
\vspace{10pt}
|
||||||
|
|
||||||
On the third round, node 3 is the intermediate round.
|
On the third round, node 3 is the new intermediate round.
|
||||||
There is a new path between nodes 2 and 4:
|
There is a new path between nodes 2 and 4:
|
||||||
|
|
||||||
\begin{center}
|
\begin{center}
|
||||||
|
@ -707,7 +707,7 @@ There is a new path between nodes 2 and 4:
|
||||||
\vspace{10pt}
|
\vspace{10pt}
|
||||||
|
|
||||||
The algorithm continues like this,
|
The algorithm continues like this,
|
||||||
until all nodes have been intermediate nodes.
|
until all nodes have been appointed intermediate nodes.
|
||||||
After the algorithm has finished, the array contains
|
After the algorithm has finished, the array contains
|
||||||
the minimum distances between any two nodes:
|
the minimum distances between any two nodes:
|
||||||
|
|
||||||
|
@ -723,8 +723,8 @@ the minimum distances between any two nodes:
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
For example, the array indicates that the
|
For example, the array tells us that the
|
||||||
shortest path between nodes 2 and 4 has length 8.
|
shortest distance between nodes 2 and 4 is 8.
|
||||||
This corresponds to the following path:
|
This corresponds to the following path:
|
||||||
|
|
||||||
\begin{center}
|
\begin{center}
|
||||||
|
@ -755,7 +755,7 @@ Floyd–Warshall algorithm that it is
|
||||||
easy to implement.
|
easy to implement.
|
||||||
The following code constructs a
|
The following code constructs a
|
||||||
distance matrix \texttt{d} where $\texttt{d}[a][b]$
|
distance matrix \texttt{d} where $\texttt{d}[a][b]$
|
||||||
is the smallest distance between nodes $a$ and $b$.
|
is the shortest distance between nodes $a$ and $b$.
|
||||||
First, the algorithm initializes \texttt{d}
|
First, the algorithm initializes \texttt{d}
|
||||||
using the adjacency matrix \texttt{v} of the graph
|
using the adjacency matrix \texttt{v} of the graph
|
||||||
($10^9$ means infinity):
|
($10^9$ means infinity):
|
||||||
|
@ -770,7 +770,7 @@ for (int i = 1; i <= n; i++) {
|
||||||
}
|
}
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
After this, the shortest paths can be found as follows:
|
After this, the shortest distances can be found as follows:
|
||||||
|
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
for (int k = 1; k <= n; k++) {
|
for (int k = 1; k <= n; k++) {
|
||||||
|
|
22
luku14.tex
22
luku14.tex
|
@ -8,7 +8,7 @@ Removing any edge from a tree divides it
|
||||||
into two components,
|
into two components,
|
||||||
and adding any edge to a tree creates a cycle.
|
and adding any edge to a tree creates a cycle.
|
||||||
Moreover, there is always a unique path between any
|
Moreover, there is always a unique path between any
|
||||||
two nodes in a tree.
|
two nodes of a tree.
|
||||||
|
|
||||||
For example, the following tree consists of 7 nodes and 6 edges:
|
For example, the following tree consists of 7 nodes and 6 edges:
|
||||||
\begin{center}
|
\begin{center}
|
||||||
|
@ -33,7 +33,7 @@ For example, the following tree consists of 7 nodes and 6 edges:
|
||||||
|
|
||||||
The \key{leaves} of a tree are the nodes
|
The \key{leaves} of a tree are the nodes
|
||||||
with degree 1, i.e., with only one neighbor.
|
with degree 1, i.e., with only one neighbor.
|
||||||
For example, the leaves in the above tree
|
For example, the leaves of the above tree
|
||||||
are nodes 3, 5, 6 and 7.
|
are nodes 3, 5, 6 and 7.
|
||||||
|
|
||||||
\index{root}
|
\index{root}
|
||||||
|
@ -73,7 +73,7 @@ is its upper neighbor.
|
||||||
Each node has exactly one parent,
|
Each node has exactly one parent,
|
||||||
except for the root that does not have a parent.
|
except for the root that does not have a parent.
|
||||||
For example, in the above tree,
|
For example, in the above tree,
|
||||||
the childern of node 4 are nodes 3 and 7,
|
the children of node 4 are nodes 3 and 7,
|
||||||
and the parent is node 1.
|
and the parent is node 1.
|
||||||
|
|
||||||
\index{subtree}
|
\index{subtree}
|
||||||
|
@ -89,9 +89,9 @@ consists of nodes 4, 3 and 7.
|
||||||
|
|
||||||
Depth-first search and breadth-first search
|
Depth-first search and breadth-first search
|
||||||
can be used for traversing the nodes in a tree.
|
can be used for traversing the nodes in a tree.
|
||||||
However, the traversal is easier to implement than
|
The traversal of a tree is easier to implement than
|
||||||
in a general graph because
|
that of a general graph, because
|
||||||
there are no cycles in the tree, and it is not
|
there are no cycles in the tree and it is not
|
||||||
possible to reach a node from multiple directions.
|
possible to reach a node from multiple directions.
|
||||||
|
|
||||||
The typical way to traverse a tree is to start
|
The typical way to traverse a tree is to start
|
||||||
|
@ -232,9 +232,9 @@ the longest path from node 1 to a leaf has length 2
|
||||||
$1 \rightarrow 4 \rightarrow 7$ or $1 \rightarrow 2 \rightarrow 6$).
|
$1 \rightarrow 4 \rightarrow 7$ or $1 \rightarrow 2 \rightarrow 6$).
|
||||||
After this, the algorithm calculates for each node
|
After this, the algorithm calculates for each node
|
||||||
$x$ the length of the longest path where $x$
|
$x$ the length of the longest path where $x$
|
||||||
is the turning point of the path.
|
is the highest point of the path.
|
||||||
The longest such path can be found by choosing
|
The longest such path can be found by choosing
|
||||||
two children with longest paths two leaves.
|
two children with longest paths to leaves.
|
||||||
For example, in the above graph,
|
For example, in the above graph,
|
||||||
nodes 2 and 4 yield the longest path for node 1.
|
nodes 2 and 4 yield the longest path for node 1.
|
||||||
|
|
||||||
|
@ -357,7 +357,7 @@ In the example graph, the distances are as follows:
|
||||||
\end{center}
|
\end{center}
|
||||||
\end{samepage}
|
\end{samepage}
|
||||||
For example, the farthest node from node 4
|
For example, the farthest node from node 4
|
||||||
in the direction of node 1 is node 6, and the distance to this
|
in the direction of node 1 is node 6, and the distance to that
|
||||||
node is 3 using the path
|
node is 3 using the path
|
||||||
$4 \rightarrow 1 \rightarrow 2 \rightarrow 6$.
|
$4 \rightarrow 1 \rightarrow 2 \rightarrow 6$.
|
||||||
|
|
||||||
|
@ -500,7 +500,7 @@ For example, the following tree is a binary tree:
|
||||||
|
|
||||||
The nodes in a binary tree have three natural
|
The nodes in a binary tree have three natural
|
||||||
orderings that correspond to different ways to
|
orderings that correspond to different ways to
|
||||||
recursively traverse the nodes:
|
recursively traverse the tree:
|
||||||
|
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item \key{pre-order}: first process the root,
|
\item \key{pre-order}: first process the root,
|
||||||
|
@ -519,7 +519,7 @@ and in post-order $[4,6,5,2,7,3,1]$.
|
||||||
|
|
||||||
If we know the pre-order and in-order
|
If we know the pre-order and in-order
|
||||||
of a tree, we can reconstruct the exact structure of the tree.
|
of a tree, we can reconstruct the exact structure of the tree.
|
||||||
For example, the tree above is the only possible tree
|
For example, the above tree is the only possible tree
|
||||||
with pre-order $[1,2,4,5,6,3,7]$ and
|
with pre-order $[1,2,4,5,6,3,7]$ and
|
||||||
in-order $[4,2,6,5,1,3,7]$.
|
in-order $[4,2,6,5,1,3,7]$.
|
||||||
In a similar way, the post-order and in-order
|
In a similar way, the post-order and in-order
|
||||||
|
|
46
luku15.tex
46
luku15.tex
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
A \key{spanning tree} of a graph consists of
|
A \key{spanning tree} of a graph consists of
|
||||||
the nodes of the graph and some of the
|
the nodes of the graph and some of the
|
||||||
edges of the graph so that there is a unique path
|
edges of the graph so that there is a path
|
||||||
between any two nodes.
|
between any two nodes.
|
||||||
Like trees in general, spanning trees are
|
Like trees in general, spanning trees are
|
||||||
connected and acyclic.
|
connected and acyclic.
|
||||||
|
@ -54,7 +54,7 @@ $3+5+9+3+2=22$.
|
||||||
|
|
||||||
A \key{minimum spanning tree}
|
A \key{minimum spanning tree}
|
||||||
is a spanning tree whose weight is as small as possible.
|
is a spanning tree whose weight is as small as possible.
|
||||||
The weight of a minimum spanning tree for the above graph
|
The weight of a minimum spanning tree for the example graph
|
||||||
is 20, and such a tree can be constructed as follows:
|
is 20, and such a tree can be constructed as follows:
|
||||||
|
|
||||||
\begin{center}
|
\begin{center}
|
||||||
|
@ -82,7 +82,7 @@ is 20, and such a tree can be constructed as follows:
|
||||||
In a similar way, a \key{maximum spanning tree}
|
In a similar way, a \key{maximum spanning tree}
|
||||||
is a spanning tree whose weight is as large as possible.
|
is a spanning tree whose weight is as large as possible.
|
||||||
The weight of a maximum spanning tree for the
|
The weight of a maximum spanning tree for the
|
||||||
above graph is 32:
|
example graph is 32:
|
||||||
|
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.9]
|
\begin{tikzpicture}[scale=0.9]
|
||||||
|
@ -302,7 +302,7 @@ will find a minimum spanning tree?
|
||||||
Let us see what happens if the minimum weight edge of
|
Let us see what happens if the minimum weight edge of
|
||||||
the graph is not included in the spanning tree.
|
the graph is not included in the spanning tree.
|
||||||
For example, suppose that a spanning tree
|
For example, suppose that a spanning tree
|
||||||
for the above graph would not contain the
|
for the previous graph would not contain the
|
||||||
minimum weight edge 5--6.
|
minimum weight edge 5--6.
|
||||||
We do not know the exact structure of such a spanning tree,
|
We do not know the exact structure of such a spanning tree,
|
||||||
but in any case it has to contain some edges.
|
but in any case it has to contain some edges.
|
||||||
|
@ -377,7 +377,7 @@ for (...) {
|
||||||
The loop goes through the edges in the list
|
The loop goes through the edges in the list
|
||||||
and always processes an edge $a$--$b$
|
and always processes an edge $a$--$b$
|
||||||
where $a$ and $b$ are two nodes.
|
where $a$ and $b$ are two nodes.
|
||||||
The code uses two functions:
|
Two functions are needed:
|
||||||
the function \texttt{same} determines
|
the function \texttt{same} determines
|
||||||
if the nodes are in the same component,
|
if the nodes are in the same component,
|
||||||
and the function \texttt{union}
|
and the function \texttt{union}
|
||||||
|
@ -386,10 +386,10 @@ joins the components that contain nodes $a$ and $b$.
|
||||||
The problem is how to efficiently implement
|
The problem is how to efficiently implement
|
||||||
the functions \texttt{same} and \texttt{union}.
|
the functions \texttt{same} and \texttt{union}.
|
||||||
One possibility is to implement the function
|
One possibility is to implement the function
|
||||||
\texttt{same} as graph traversal and check if
|
\texttt{same} as a graph traversal and check if
|
||||||
we can reach node $b$ from node $a$.
|
we can get from node $a$ to node $b$.
|
||||||
However, the time complexity of such a function
|
However, the time complexity of such a function
|
||||||
would be $O(n+m)$,
|
would be $O(n+m)$
|
||||||
and the resulting algorithm would be slow,
|
and the resulting algorithm would be slow,
|
||||||
because the function \texttt{same} will be called for each edge in the graph.
|
because the function \texttt{same} will be called for each edge in the graph.
|
||||||
|
|
||||||
|
@ -415,7 +415,7 @@ of the set that contains a given element.
|
||||||
|
|
||||||
In a union-find structure, one element in each set
|
In a union-find structure, one element in each set
|
||||||
is the representative of the set,
|
is the representative of the set,
|
||||||
and there is a chain from any other element in the
|
and there is a chain from any other element of the
|
||||||
set to the representative.
|
set to the representative.
|
||||||
For example, assume that the sets are
|
For example, assume that the sets are
|
||||||
$\{1,4,7\}$, $\{5\}$ and $\{2,3,6,8\}$:
|
$\{1,4,7\}$, $\{5\}$ and $\{2,3,6,8\}$:
|
||||||
|
@ -439,13 +439,13 @@ $\{1,4,7\}$, $\{5\}$ and $\{2,3,6,8\}$:
|
||||||
|
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
In this example the representatives
|
In this case the representatives
|
||||||
of the sets are 4, 5 and 2.
|
of the sets are 4, 5 and 2.
|
||||||
For each element, we can find its representative
|
For each element, we can find its representative
|
||||||
by following the chain that begins at the element.
|
by following the chain that begins at the element.
|
||||||
For example, the element 2 is the representative
|
For example, the element 2 is the representative
|
||||||
for the element 6, because
|
for the element 6, because
|
||||||
there is a chain $6 \rightarrow 3 \rightarrow 2$.
|
we follow the chain $6 \rightarrow 3 \rightarrow 2$.
|
||||||
Two elements belong to the same set exactly when
|
Two elements belong to the same set exactly when
|
||||||
their representatives are the same.
|
their representatives are the same.
|
||||||
|
|
||||||
|
@ -478,20 +478,21 @@ can be joined as follows:
|
||||||
|
|
||||||
The resulting set contains the elements
|
The resulting set contains the elements
|
||||||
$\{1,2,3,4,6,7,8\}$.
|
$\{1,2,3,4,6,7,8\}$.
|
||||||
From this on, the element 2 will be the representative
|
From this on, the element 2 is the representative
|
||||||
for the entire set and the old representative 4
|
for the entire set and the old representative 4
|
||||||
will point to the element 2.
|
points to the element 2.
|
||||||
|
|
||||||
The efficiency of the structure depends on
|
The efficiency of the union-find structure depends on
|
||||||
the way the sets are joined.
|
how the sets are joined.
|
||||||
It turns out that we can follow a simple strategy:
|
It turns out that we can follow a simple strategy:
|
||||||
always connect the representative of the
|
always connect the representative of the
|
||||||
smaller set to the representative of the larger set
|
smaller set to the representative of the larger set
|
||||||
(or if the sets are of equal size,
|
(or if the sets are of equal size,
|
||||||
we can make an arbitrary choice).
|
we can make an arbitrary choice).
|
||||||
Using this strategy, the length of any chain
|
Using this strategy, the length of any chain
|
||||||
will be $O(\log n)$, so we can always efficiently
|
will be $O(\log n)$, so we can
|
||||||
find the representative of any element by following the chain.
|
find the representative of any element
|
||||||
|
efficiently by following the corresponding chain.
|
||||||
|
|
||||||
\subsubsection{Implementation}
|
\subsubsection{Implementation}
|
||||||
|
|
||||||
|
@ -570,9 +571,9 @@ the smaller set to the larger set.
|
||||||
for finding a minimum spanning tree.
|
for finding a minimum spanning tree.
|
||||||
The algorithm first adds an arbitrary node
|
The algorithm first adds an arbitrary node
|
||||||
to the tree.
|
to the tree.
|
||||||
After this, the algorithm always selects an edge
|
After this, the algorithm always chooses
|
||||||
whose weight is as small as possible and
|
a minimum-weight edge that
|
||||||
that adds a new node to the tree.
|
adds a new node to the tree.
|
||||||
Finally, all nodes have been added to the tree
|
Finally, all nodes have been added to the tree
|
||||||
and a minimum spanning tree has been found.
|
and a minimum spanning tree has been found.
|
||||||
|
|
||||||
|
@ -627,8 +628,9 @@ Initially, there are no edges between the nodes:
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
An arbitrary node can be the starting node,
|
An arbitrary node can be the starting node,
|
||||||
so let us select node 1.
|
so let us choose node 1.
|
||||||
First, an edge with weight 3 connects nodes 1 and 2:
|
First, we add node 2 that is connected by
|
||||||
|
an edge of weight 3:
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.9]
|
\begin{tikzpicture}[scale=0.9]
|
||||||
\node[draw, circle] (1) at (1.5,2) {$1$};
|
\node[draw, circle] (1) at (1.5,2) {$1$};
|
||||||
|
|
Loading…
Reference in New Issue