Union-find structure
This commit is contained in:
parent
b0f75a819e
commit
bd6525b526
198
luku15.tex
198
luku15.tex
|
@ -394,35 +394,29 @@ called for each edge in the graph.
|
||||||
We will solve the problem using a union-find structure
|
We will solve the problem using a union-find structure
|
||||||
that implements both the functions in $O(\log n)$ time.
|
that implements both the functions in $O(\log n)$ time.
|
||||||
Thus, the time complexity of Kruskal's algorithm
|
Thus, the time complexity of Kruskal's algorithm
|
||||||
will be only $O(m \log n)$ after sorting the edge list.
|
will be $O(m \log n)$ after sorting the edge list.
|
||||||
|
|
||||||
\section{Union-find-rakenne}
|
\section{Union-find structure}
|
||||||
|
|
||||||
\index{union-find-rakenne}
|
\index{union-find structure}
|
||||||
|
|
||||||
\key{Union-find-rakenne} pitää yllä
|
The \key{union-find structure} maintains
|
||||||
alkiojoukkoja.
|
a collection of sets.
|
||||||
Joukot ovat erillisiä,
|
The sets are disjoint, so no element
|
||||||
eli tietty alkio on tarkalleen
|
belongs to more than one set.
|
||||||
yhdessä joukossa.
|
Two $O(\log n)$ time operations are supported.
|
||||||
Rakenne tarjoaa kaksi operaatiota,
|
The first operation checks if two elements
|
||||||
jotka toimivat ajassa $O(\log n)$.
|
belong to the same set,
|
||||||
Ensimmäinen operaatio tarkistaa,
|
and the second operation joins two sets into a single set.
|
||||||
ovatko kaksi alkiota samassa joukossa.
|
|
||||||
Toinen operaatio yhdistää kaksi
|
|
||||||
joukkoa toisiinsa.
|
|
||||||
|
|
||||||
\subsubsection{Rakenne}
|
\subsubsection{Structure}
|
||||||
|
|
||||||
Union-find-rakenteessa jokaisella
|
In the union-find structure, one element in each set
|
||||||
joukolla on edustaja-alkio.
|
is the representative of the set.
|
||||||
Kaikki muut joukon alkiot osoittavat
|
All other elements in the set point to the
|
||||||
edustajaan joko suoraan tai
|
representative directly or through other elements in the set.
|
||||||
muiden alkioiden kautta.
|
For example, in the following picture there are three sets:
|
||||||
|
$\{1,4,7\}$, $\{5\}$ and $\{2,3,6,8\}$.
|
||||||
Esimerkiksi jos joukot ovat
|
|
||||||
$\{1,4,7\}$, $\{5\}$ ja $\{2,3,6,8\}$,
|
|
||||||
tilanne voisi olla:
|
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}
|
\begin{tikzpicture}
|
||||||
\node[draw, circle] (1) at (0,-1) {$1$};
|
\node[draw, circle] (1) at (0,-1) {$1$};
|
||||||
|
@ -443,26 +437,23 @@ tilanne voisi olla:
|
||||||
|
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
Tässä tapauksessa alkiot 4, 5 ja 2
|
In this case the representatives
|
||||||
ovat joukkojen edustajat.
|
of the sets are 4, 5 and 2.
|
||||||
Minkä tahansa alkion edustaja
|
For each element, we can find the representative
|
||||||
löytyy kulkemalla alkiosta lähtevää polkua
|
for the corresponding set by following the
|
||||||
eteenpäin niin kauan, kunnes polku päättyy.
|
path that begins at the element.
|
||||||
Esimerkiksi alkion 6 edustaja on 2,
|
For example, element 2 is the representative for the set
|
||||||
koska alkiosta 6 lähtevä
|
that contains element 6 because
|
||||||
polku on $6 \rightarrow 3 \rightarrow 2$.
|
the path is $6 \rightarrow 3 \rightarrow 2$.
|
||||||
Tämän avulla voi selvittää,
|
Thus, two elements belong to the same set exactly when
|
||||||
ovatko kaksi alkiota samassa joukossa:
|
they point to the same representative.
|
||||||
jos kummankin alkion edustaja on sama,
|
|
||||||
alkiot ovat samassa joukossa,
|
|
||||||
ja muuten ne ovat eri joukoissa.
|
|
||||||
|
|
||||||
Kahden joukon yhdistäminen tapahtuu
|
Two sets can be combined by connecting the
|
||||||
valitsemalla toinen edustaja
|
representative of one set to the
|
||||||
joukkojen yhteiseksi edustajaksi
|
representative of another set.
|
||||||
ja kytkemällä toinen edustaja siihen.
|
For example, sets
|
||||||
Esimerkiksi joukot $\{1,4,7\}$ ja $\{2,3,6,8\}$
|
$\{1,4,7\}$ and $\{2,3,6,8\}$
|
||||||
voi yhdistää näin joukoksi $\{1,2,3,4,6,7,8\}$:
|
can be combined as follows into set $\{1,2,3,4,6,7,8\}$:
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}
|
\begin{tikzpicture}
|
||||||
\node[draw, circle] (1) at (2,-1) {$1$};
|
\node[draw, circle] (1) at (2,-1) {$1$};
|
||||||
|
@ -484,73 +475,75 @@ voi yhdistää näin joukoksi $\{1,2,3,4,6,7,8\}$:
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
Joukkojen yhteiseksi edustajaksi valitaan alkio 2,
|
In this case, element 2 becomes the representative
|
||||||
minkä vuoksi alkio 4 yhdistetään siihen.
|
for the whole set and the old representative 4
|
||||||
Tästä lähtien alkio 2 edustaa kaikkia joukon alkioita.
|
points to it.
|
||||||
|
|
||||||
Tehokkuuden kannalta oleellista on,
|
The efficiency of the operations depends on
|
||||||
miten yhdistäminen tapahtuu.
|
the way the sets are combined.
|
||||||
Osoittautuu, että ratkaisu on yksinkertainen:
|
It turns out that we can follow a simple strategy
|
||||||
riittää yhdistää aina pienempi joukko suurempaan,
|
and always connect the representative of the
|
||||||
tai kummin päin tahansa,
|
smaller set to the representative of the larger set
|
||||||
jos joukot ovat yhtä suuret.
|
(or, if the sets are of the same size,
|
||||||
Tällöin pisin ketju
|
both choices are fine).
|
||||||
alkiosta edustajaan on aina luokkaa $O(\log n)$,
|
Using this strategy, the length of a path from
|
||||||
koska jokainen askel eteenpäin
|
a element in a set to a representative is
|
||||||
ketjussa kaksinkertaistaa
|
always $O(\log n)$ because each step forward
|
||||||
vastaavan joukon koon.
|
in the path doubles the size of the corresponding set.
|
||||||
|
|
||||||
\subsubsection{Toteutus}
|
\subsubsection{Implementation}
|
||||||
|
|
||||||
Union-find-rakenne on kätevää toteuttaa
|
We can implement the union-find structure
|
||||||
taulukoiden avulla.
|
using arrays.
|
||||||
Seuraavassa toteutuksessa taulukko \texttt{k}
|
In the following implementation,
|
||||||
viittaa seuraavaan alkioon ketjussa
|
array \texttt{k} contains for each element
|
||||||
tai alkioon itseensä, jos alkio on edustaja.
|
the next element
|
||||||
Taulukko \texttt{s} taas kertoo jokaiselle edustajalle,
|
in the path, or the element itself if it is
|
||||||
kuinka monta alkiota niiden joukossa on.
|
a representative,
|
||||||
|
and array \texttt{s} indicates for each representative
|
||||||
Aluksi jokainen alkio on omassa joukossaan,
|
the size of the corresponding set.
|
||||||
jonka koko on 1:
|
|
||||||
|
|
||||||
|
Initially, each element has an own set with size 1:
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
for (int i = 1; i <= n; i++) k[i] = i;
|
for (int i = 1; i <= n; i++) k[i] = i;
|
||||||
for (int i = 1; i <= n; i++) s[i] = 1;
|
for (int i = 1; i <= n; i++) s[i] = 1;
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
Funktio \texttt{id} kertoo alkion $x$
|
The function \texttt{find} returns
|
||||||
joukon edustajan. Alkion edustaja löytyy
|
the representative for element $x$.
|
||||||
käymällä ketju läpi alkiosta $x$ alkaen.
|
The representative can be found by following
|
||||||
|
the path that begins at element $x$.
|
||||||
|
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
int id(int x) {
|
int find(int x) {
|
||||||
while (x != k[x]) x = k[x];
|
while (x != k[x]) x = k[x];
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
Funktio \texttt{sama} kertoo,
|
The function \texttt{same} finds out
|
||||||
ovatko alkiot $a$ ja $b$ samassa joukossa.
|
whether elements $a$ and $b$ belong to the same set.
|
||||||
Tämä onnistuu helposti funktion
|
This can easily be done by using the
|
||||||
\texttt{id} avulla.
|
function \texttt{find}.
|
||||||
|
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
bool sama(int a, int b) {
|
bool same(int a, int b) {
|
||||||
return id(a) == id(b);
|
return find(a) == find(b);
|
||||||
}
|
}
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
\begin{samepage}
|
\begin{samepage}
|
||||||
Funktio \texttt{liita} yhdistää
|
The function \texttt{union} combines the sets
|
||||||
puolestaan alkioiden $a$ ja $b$ osoittamat
|
that contain elements $a$ and $b$
|
||||||
joukot yhdeksi joukoksi.
|
into a single set.
|
||||||
Funktio etsii ensin joukkojen edustajat
|
The function first finds the representatives
|
||||||
ja yhdistää sitten pienemmän joukon suurempaan.
|
of the sets and then connects the smaller
|
||||||
|
set to the larger set.
|
||||||
|
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
void liita(int a, int b) {
|
void union(int a, int b) {
|
||||||
a = id(a);
|
a = find(a);
|
||||||
b = id(b);
|
b = find(b);
|
||||||
if (s[b] > s[a]) swap(a,b);
|
if (s[b] > s[a]) swap(a,b);
|
||||||
s[a] += s[b];
|
s[a] += s[b];
|
||||||
k[b] = a;
|
k[b] = a;
|
||||||
|
@ -558,31 +551,14 @@ void liita(int a, int b) {
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
\end{samepage}
|
\end{samepage}
|
||||||
|
|
||||||
Funktion \texttt{id} aikavaativuus on $O(\log n)$
|
The time complexity of the function \texttt{find}
|
||||||
olettaen, että ketjun pituus on luokkaa $O(\log n)$.
|
is $O(\log n)$ assuming that the length of the
|
||||||
Niinpä myös funktioiden \texttt{sama} ja \texttt{liita}
|
path is $O(\log n)$.
|
||||||
aikavaativuus on $O(\log n)$.
|
Thus, the functions \texttt{same} and \texttt{union}
|
||||||
Funktio \texttt{liita} varmistaa,
|
also work in $O(\log n)$ time.
|
||||||
että ketjun pituus on luokkaa $O(\log n)$
|
The function \texttt{union} ensures that the
|
||||||
yhdistämällä pienemmän joukon suurempaan.
|
length of each path is $O(\log n)$ by connecting
|
||||||
|
the smaller set to the larger set.
|
||||||
% Funktiota \texttt{id} on mahdollista vielä tehostaa
|
|
||||||
% seuraavasti:
|
|
||||||
%
|
|
||||||
% \begin{lstlisting}
|
|
||||||
% int id(int x) {
|
|
||||||
% if (x == k[x]) return x;
|
|
||||||
% return k[x] = id(x);
|
|
||||||
% }
|
|
||||||
% \end{lstlisting}
|
|
||||||
%
|
|
||||||
% Nyt joukon edustajan etsimisen yhteydessä kaikki ketjun
|
|
||||||
% alkiot laitetaan osoittamaan suoraan edustajaan.
|
|
||||||
% On mahdollista osoittaa, että tämän avulla
|
|
||||||
% funktioiden \texttt{sama} ja \texttt{liita}
|
|
||||||
% aikavaativuus on tasoitetusti
|
|
||||||
% vain $O(\alpha(n))$, missä $\alpha(n)$ on
|
|
||||||
% hyvin hitaasti kasvava käänteinen Ackermannin funktio.
|
|
||||||
|
|
||||||
\section{Primin algoritmi}
|
\section{Primin algoritmi}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue