Longest increasing subsequence

This commit is contained in:
Antti H S Laaksonen 2017-01-02 19:55:47 +02:00
parent 9b75316ad6
commit 7dac0d0ff5
1 changed files with 48 additions and 41 deletions

View File

@ -389,20 +389,20 @@ we will now go through a set of problems
that show further examples how dynamic that show further examples how dynamic
programming can be used. programming can be used.
\section{Pisin nouseva alijono} \section{Longest increasing subsequence}
\index{pisin nouseva alijono@pisin nouseva alijono} \index{longest increasing subsequence}
Annettuna on taulukko, jossa on $n$ Given an array that contains $n$
kokonaislukua $x_1,x_2,\ldots,x_n$. numbers $x_1,x_2,\ldots,x_n$,
Tehtävänä on selvittää, our task is find the
kuinka pitkä on taulukon \key{longest increasing subsequence}
\key{pisin nouseva alijono} in the array.
eli vasemmalta oikealle kulkeva This is a sequence of array elements
ketju taulukon alkioita, that goes from the left to the right,
jotka on valittu niin, and each element in the sequence is larger
että jokainen alkio on edellistä suurempi. than the previous element.
Esimerkiksi taulukossa For example, in the array
\begin{center} \begin{center}
\begin{tikzpicture}[scale=0.7] \begin{tikzpicture}[scale=0.7]
@ -427,7 +427,8 @@ Esimerkiksi taulukossa
\node at (7.5,1.4) {$8$}; \node at (7.5,1.4) {$8$};
\end{tikzpicture} \end{tikzpicture}
\end{center} \end{center}
pisin nouseva alijono sisältää 4 alkiota: the longest increasing subsequence
contains 4 elements:
\begin{center} \begin{center}
\begin{tikzpicture}[scale=0.7] \begin{tikzpicture}[scale=0.7]
\fill[color=lightgray] (1,0) rectangle (2,1); \fill[color=lightgray] (1,0) rectangle (2,1);
@ -460,12 +461,14 @@ pisin nouseva alijono sisältää 4 alkiota:
\end{tikzpicture} \end{tikzpicture}
\end{center} \end{center}
Merkitään $f(k)$ kohtaan $k$ päättyvän Let $f(k)$ be the length of the
pisimmän nousevan alijonon pituutta, longest increasing subsequence
jolloin ratkaisu tehtävään on suurin that ends to index $k$.
arvoista $f(1),f(2),\ldots,f(n)$. Thus, the answer for the problem
Esimerkiksi yllä olevassa taulukossa is the largest of values
funktion arvot ovat seuraavat: $f(1),f(2),\ldots,f(n)$.
For example, in the above array
the values for the function are as follows:
\[ \[
\begin{array}{lcl} \begin{array}{lcl}
f(1) & = & 1 \\ f(1) & = & 1 \\
@ -479,33 +482,37 @@ f(8) & = & 2 \\
\end{array} \end{array}
\] \]
Arvon $f(k)$ laskemisessa on kaksi vaihtoehtoa, When calculating the value $f(k)$,
millainen kohtaan $k$ päättyvä pisin nouseva alijono on: there are two possibilities how the subsequence
that ends to index $k$ is constructed:
\begin{enumerate} \begin{enumerate}
\item Pisin nouseva alijono sisältää vain luvun $x_k$, \item The subsequence
jolloin $f(k)=1$. only contains the element $x_k$, so $f(k)=1$.
\item Valitaan jokin kohta $i$, jolle pätee $i<k$ \item We choose some index $i$ for which $i<k$
ja $x_i<x_k$. and $x_i<x_k$.
Pisin nouseva alijono saadaan liittämällä We extend the longest increasing subsequence
kohtaan $i$ päättyvän pisimmän nousevan alijonon perään luku $x_k$. that ends to index $i$ by adding the element $x_k$
Tällöin $f(k)=f(i)+1$. to it. In this case $f(k)=f(i)+1$.
\end{enumerate} \end{enumerate}
Tarkastellaan esimerkkinä arvon $f(7)$ laskemista. Consider calculating the value $f(7)$.
Paras ratkaisu on ottaa pohjaksi kohtaan 5 The best solution is to extend the longest
päättyvä pisin nouseva alijono $[2,5,7]$ increasing subsequence that ends to index 5,
ja lisätä sen perään luku $x_7=8$. i.e., the sequence $[2,5,7]$, by adding
Tuloksena on alijono $[2,5,7,8]$ ja $f(7)=f(5)+1=4$. the element $x_7=8$.
The result is
$[2,5,7,8]$, and $f(7)=f(5)+1=4$.
Suoraviivainen tapa toteuttaa algoritmi on A straightforward way to calculate the
käydä kussakin kohdassa $k$ läpi kaikki kohdat value $f(k)$ is to
$i=1,2,\ldots,k-1$, joissa voi olla alijonon go through all indices
edellinen luku. $i=1,2,\ldots,k-1$ that can contain the
Tällaisen algoritmin aikavaativuus on $O(n^2)$. previous element in the subsequence.
Yllättävää kyllä, algoritmin voi toteuttaa myös The time complexity of such an algorithm is $O(n^2)$.
ajassa $O(n \log n)$, mutta tämä on vaikeampaa. Surprisingly, it is also possible to solve the
problem in $O(n \log n)$ time, but this is more difficult.
\section{Reitinhaku ruudukossa} \section{Path in a grid}
Seuraava tehtävämme on etsiä reitti Seuraava tehtävämme on etsiä reitti
$n \times n$ -ruudukon vasemmasta yläkulmasta $n \times n$ -ruudukon vasemmasta yläkulmasta