Chapter 8 first version

This commit is contained in:
Antti H S Laaksonen 2017-01-03 02:20:01 +02:00
parent 173e5e75dd
commit 612e412dda
1 changed files with 52 additions and 50 deletions

View File

@ -592,39 +592,38 @@ Thus, each element causes $O(1)$ operations
to the chain, and the total time complexity to the chain, and the total time complexity
of the algorithm is $O(n)$. of the algorithm is $O(n)$.
\section{Liukuvan ikkunan minimi} \section{Sliding window minimum}
\index{liukuva ikkuna} \index{sliding window}
\index{liukuvan ikkunan minimi@liukuvan ikkunan minimi} \index{sliding window minimum}
\key{Liukuva ikkuna} on taulukon halki kulkeva A \key{sliding window} is an active subarray
aktiivinen alitaulukko, jonka pituus on vakio. that moves through the array whose size is constant.
Jokaisessa liukuvan ikkunan sijainnissa At each position of the window,
halutaan tyypillisesti laskea jotain tietoa we typically want to calculate some information
ikkunan alueelle osuvista alkioista. about the elements inside the window.
Kiinnostava tehtävä on pitää yllä An interesting problem is to maintain
\key{liukuvan ikkunan minimiä}. the \key{sliding window minimum}.
Tämä tarkoittaa, että jokaisessa liukuvan ikkunan This means that at each position of the window,
sijainnissa tulee ilmoittaa pienin alkio we should report the smallest element inside the window.
ikkunan alueella.
Liukuvan ikkunan minimit voi laskea The sliding window minima can be calculated
lähes samalla tavalla kuin lähimmät using the same idea that we used for calculating
pienimmät edeltäjät. the nearest smaller elements.
Ideana on pitää yllä ketjua, jonka alussa The idea is to maintain a chain whose
on ikkunan viimeinen luku ja jossa jokainen first element is the last element in the window,
luku on edellistä pienempi. Joka vaiheessa and each element is smaller than the previous element.
ketjun viimeinen luku on ikkunan pienin luku. The last element in the chain is always the
Kun liukuva ikkuna liikkuu eteenpäin ja välille smallest element inside the window.
tulee uusi luku, ketjusta poistetaan kaikki luvut, When the sliding window moves forward and
jotka ovat uutta lukua suurempia. a new element appears, we remove all elements
Tämän jälkeen uusi luku lisätään ketjun alkuun. from the chain that are larger than the new element.
Lisäksi jos ketjun viimeinen luku ei enää kuulu After this, we add the new number to the chain.
välille, se poistetaan ketjusta. In addition, if the last element in the chain
doesn't belong to the window anymore, it is removed from the chain.
Tarkastellaan esimerkkinä, kuinka algoritmi selvittää As an example, consider the following array
minimit seuraavassa taulukossa, when the window size is $k=4$:
kun ikkunan koko $k=4$.
\begin{center} \begin{center}
\begin{tikzpicture}[scale=0.7] \begin{tikzpicture}[scale=0.7]
@ -651,8 +650,8 @@ kun ikkunan koko $k=4$.
\end{tikzpicture} \end{tikzpicture}
\end{center} \end{center}
Liukuva ikkuna aloittaa matkansa taulukon vasemmasta reunasta. The sliding window begins from the left border of the array.
Ensimmäisessä ikkunan sijainnissa pienin luku on 1: At the first window position, the smallest element is 1:
\begin{center} \begin{center}
\begin{tikzpicture}[scale=0.7] \begin{tikzpicture}[scale=0.7]
\fill[color=lightgray] (0,0) rectangle (4,1); \fill[color=lightgray] (0,0) rectangle (4,1);
@ -683,10 +682,11 @@ Ensimmäisessä ikkunan sijainnissa pienin luku on 1:
\end{tikzpicture} \end{tikzpicture}
\end{center} \end{center}
Kun ikkuna siirtyy eteenpäin, mukaan tulee luku 3, Then the window moves one step forward.
joka on pienempi kuin luvut 5 ja 4 ketjun alussa. The new number 3 is smaller than the numbers
Niinpä luvut 5 ja 4 poistuvat ketjusta ja luku 3 5 and 4 in the chain, so the numbers 5 and 4
siirtyy sen alkuun. Pienin luku on edelleen 1. are removed and the number 3 is added to the chain.
The smallest element is 1 as before.
\begin{center} \begin{center}
\begin{tikzpicture}[scale=0.7] \begin{tikzpicture}[scale=0.7]
\fill[color=lightgray] (1,0) rectangle (5,1); \fill[color=lightgray] (1,0) rectangle (5,1);
@ -716,10 +716,11 @@ siirtyy sen alkuun. Pienin luku on edelleen 1.
\end{tikzpicture} \end{tikzpicture}
\end{center} \end{center}
Ikkuna siirtyy taas eteenpäin, minkä seurauksena pienin luku 1 After this, the window moves again and the smallest element 1
putoaa pois ikkunasta. Niinpä se poistetaan ketjun lopusta doesn't belong to the window anymore.
ja uusi pienin luku on 3. Lisäksi uusi ikkunaan tuleva luku 4 Thus, it is removed from the chain and the smallest
lisätään ketjun alkuun. element is now 3. In addition, the new number 4
is added to the chain.
\begin{center} \begin{center}
\begin{tikzpicture}[scale=0.7] \begin{tikzpicture}[scale=0.7]
\fill[color=lightgray] (2,0) rectangle (6,1); \fill[color=lightgray] (2,0) rectangle (6,1);
@ -748,10 +749,10 @@ lisätään ketjun alkuun.
\end{tikzpicture} \end{tikzpicture}
\end{center} \end{center}
Seuraavaksi ikkunaan tuleva luku 1 on pienempi The next new element 1 is smaller than all elements
kuin kaikki ketjussa olevat luvut. in the chain.
Tämän seurauksena koko ketju tyhjentyy ja Thus, all elements are removed from the chain
siihen jää vain luku 1: and it will only contain the element 1:
\begin{center} \begin{center}
\begin{tikzpicture}[scale=0.7] \begin{tikzpicture}[scale=0.7]
\fill[color=lightgray] (3,0) rectangle (7,1); \fill[color=lightgray] (3,0) rectangle (7,1);
@ -782,9 +783,10 @@ siihen jää vain luku 1:
\end{tikzpicture} \end{tikzpicture}
\end{center} \end{center}
Lopuksi ikkuna saapuu viimeiseen sijaintiinsa. Finally the window reaches its last position.
Luku 2 lisätään ketjun alkuun, The number 2 is added to the chain,
mutta ikkunan pienin luku on edelleen 1. but the smallest element inside the window
is still 1.
\begin{center} \begin{center}
\begin{tikzpicture}[scale=0.7] \begin{tikzpicture}[scale=0.7]
\fill[color=lightgray] (4,0) rectangle (8,1); \fill[color=lightgray] (4,0) rectangle (8,1);
@ -813,10 +815,10 @@ mutta ikkunan pienin luku on edelleen 1.
\end{tikzpicture} \end{tikzpicture}
\end{center} \end{center}
Tässäkin algoritmissa jokainen taulukon luku lisätään Also in this algorithm, each element in the array
ketjuun tarkalleen kerran ja poistetaan ketjusta korkeintaan kerran, is added to the chain exactly once and
joko ketjun alusta tai ketjun lopusta. removed from the chain at most once.
Niinpä algoritmin kokonaisaikavaativuus on $O(n)$. Thus, the total time complexity of the algorithm is $O(n)$.