]> mj.ucw.cz Git - ads1.git/commitdiff
Nulta verze trideni.
authorMartin Mares <mj@ucw.cz>
Fri, 11 May 2007 13:07:59 +0000 (15:07 +0200)
committerMartin Mares <mj@ucw.cz>
Fri, 11 May 2007 13:07:59 +0000 (15:07 +0200)
6-trideni/6-trideni.tex [new file with mode: 0644]
6-trideni/Makefile [new file with mode: 0644]
all/Makefile

diff --git a/6-trideni/6-trideni.tex b/6-trideni/6-trideni.tex
new file mode 100644 (file)
index 0000000..54a77db
--- /dev/null
@@ -0,0 +1,194 @@
+\input ../lecnotes.tex
+
+\prednaska{6}{Tøídìní v lineárním èase}{(zapsal M.~Kupec, J.~Volec, J.~Ivánek)}
+
+\h{Lineární èas}
+Na minulých pøed¹kách jsme si ukázali tøídìní v èase $ \O(N\log{N}) $, a taky dokázali, ¾e líp to nejde. Jak je tedy mo¾né tøídit v lineárním èase ?
+
+V¹echny dosud pøedvedené alrogitmy tøídily pouze pomocí porovnávní hodnot na vstupu. Ale co kdy¾ o vstupu víme víc, tøeba rozsah hodnot na vstup, nedá se toho vy¾ít ?
+
+Následující algoritmy vyu¾ívají znalosti rozsahu hodnot na vstupu, a toho, ¾e tento rozsah je malý.
+
+\h{Counting sort}
+
+Counting sort je algoritmus pro tøídìní $ 1 \dots R $ èísel. Tøídí v èase $ \O(N + R) $ s pamì»ovou nároèností $ O(R) $.
+
+\s{Algoritmus:} (tøídìní mno¾iny $X$ o velikosti $N$ pomocí {\sc Counting sort}u)
+
+\algo
+\:Pro $ i \leftarrow 1 $ do $R$ opakuj:
+\::$ P[i] \leftarrow 0 $
+\:Pro $ i \leftarrow 1 $ do $N$ opakuj:
+\::$ P[X[i]] \leftarrow P[X[i] + 1 $
+\endalgo
+
+\h{Pøihrádkové tøídìní}
+
+Counting sort nám moc nepomù¾e pokud chceme tøídit neco jiného ne¾ èísla, ale i to se dá øe¹it. Pøihrádkové, popøípadì kbelíkové tøídìní, nebo-li Bucket sort umí tøídit mno¾inu prvkù oèíslovaných èísly $ 1 \ldots R $.
+
+\>Potøebuje k tomu èas $ \O(N + R) $ a pamì» $ \O(N + R) $.
+
+Bucket sort ma je¹tì jednu pøíjemnou vlastnost, jedná se o stabilní tøídìní.
+
+\s{Definice:} {\sc Stabilní tøídìní} je takové, ¾e ka¾dé 2 prvky vstupu se stejnou hodnotou klíèe jsou na výstupu ve stejnìm poøadí jako na vstupu.
+
+\s{Algoritmus:} (tøídìní mno¾iny $X$ o velikosti $N$ pomocí {\sc Bucket sort}u)
+\algo
+\:Pro $ k \leftarrow 1 $ do $R$ opakuj:
+\::$ C[k] \leftarrow 0 $
+\:Pro $ i \leftarrow 1 $ do $N$ opakuj:
+\::$ C[x[i]] \leftarrow C[X[i]] + 1 $
+\:$ b[1] \leftarrow 1 $
+\:Pro $ k \leftarrow 2 $ do $R$ opakuj:
+\::$ b[k] \leftarrow b[k - 1] + c[b - 1] $
+\:Pro $ i \leftarrow 1 $ do $N$ opakuj:
+\::$ p \leftarrow X[i] $
+\::$ Y[b[p]] \leftarrow p $
+\::$ b[p] \leftarrow b[p] + 1 $
+\endalgo
+
+\h{Lexikografické tøídìní k-tic}
+Mìjme $n$ $k$-tic z $ \{1 \ldots R \}^k $ (prvky $k$-tice jsou $ 1 \ldots R $), seøazení $k$-tic slovníkovì (lexikograficky).
+Mù¾eme pou¾ít metodu rozdìl a panuj, setøídíme nejprve podle první souøadnice $k$-tic a pak se rekurzivnì zavoláme na ka¾dou pøihrádku a tøídíme podle následující souøadnice.
+
+Nebo mù¾eme vyu¾ít toho, ¾e bucket-sort je stabilní a tøídit takto:
+\algo
+\:Pro $ i \leftarrow k $ do $1$ opakuj:
+\::BucketSort podle $i$-té souøadnice
+\endalgo
+
+Pro pøehlednost v následujícím pozorování oznaème $ l = k - i + 1 $, co¾ pøesnì odpovídá tomu, v kolikátém prùchodu cyklu jsme.
+
+\s{Pozorování:}
+po $l$-tém prùchodu cyklem jsou prvky uspoøádány lexikograficky podle $i$-té a¾ $k$-té souøadnice.
+
+\proof
+Indukcí podle $l$
+% FIXME nevim jak presne by mel byt list
+\itemize
+\next Pro $ l = 1 $ jsou prvky uspoøádány podle poslední souøadnice
+\next Po $l$ prùchodech ji¾ máme prvky setøízeny lexikograficky podle $i$-té a¾ $k$-té souøadnice a spou¹tíme $(l + 1)$-ní prùchod, tj. budeme tøídít podle $(i - 1)$-ní souøadnice.
+Proto¾e Bucket sort tøídí stabilnì, zùstanou prvky se stejnou $(i - 1)$-ní souøadnicí vùèi sobì seøazeny tak, jak byly seøazeny na vstupu.
+Z IP tam v¹ak byly seøazeny lexikograficky podle $i$-té a¾ $k$-té souøadnice. Tudí¾ po $(l + 1)$-ním prùchodu jsou prvky seøazeny podle $(i - 1)$-ní a¾ $k$-té souøadnice.
+\endlist
+\qed
+
+Èasová slo¾itost je $\O( k * (n + R))$, co¾ je lineární s délkou vstupu $(k * n)$ a pamì»ová slo¾itost je $\O(n + R)$.
+
+\h{Tøídìní $ 1 \ldots R $ èísel podruhé}
+Zvolíme základ $Z$ a èísla zapí¹eme v soustavì o základu $Z$, èím¾ získáme $ ( \lfloor \log_z{R} \rfloor +1)-tice $, na které spustíme pøedcházející algoritmus.
+Díky tomu budeme tøídít v èase $\O({\log{R} \over (\log{Z})} * (n + Z))$. A jak zvolit vhodnì $Z$?
+
+Pokud bychom zvolili $ Z = konstanta $, èasová slo¾itost bude $\O(\log{R} * n) $, co¾ mù¾e být a¾ $ n * \log{n} $.
+Zvolíme-li $ Z = n $, dostáváme $ \O({\log{R} \over \log{n}} * n) $, co¾ pro $ R \leq n^\alpha $ znamená $ \O(\alpha * n) $.
+
+% FIXME dopsat prepsat..v reseni
+\h{Tøídìní øetìzcù}
+Mìjme $n$ øetìzcù dlouhých $ l_1, l_2, \ldots, l_n $ tøídíme $ O(n + \sum_{i}{l_i}) $
+Problém: øetìzce nejsou stejnì dlouhé, je potøeba se vyhnout pøehazování mezer
+
+\h{K èemu je tøídìní dobré?}
+
+Abychom mohli rychleji hledat - v logaritmickém èase pùlením intervalù.
+Pokud chceme zjistit, zda se nìjaké hodnoty opakují, nejde to udìlat lépe ne¾ data setøídít. 
+
+\h{Sorting Zoo}
+
+% FIXME pridat svisle cary..mozna i vodorovne
+
+$$
+\vbox {
+\halign{$#$ \hfil & \quad \hfil $#$ & \quad \hfil $#$ & \quad \hfil $#$ \cr
+& \O(1) & \O(\log{N}) & \O(N) \cr
+\noalign{\medskip\hrule\bigskip}
+\O(N^2) & Buble &   & \cr
+\O(N\log{N}) & Heap & Quick & Merge \cr
+\O(N) &   &   & Bucket \cr
+}
+}
+$$
+
+\h{Vyhledávací stromy}
+Problém: chceme udr¾ovat nìjaká data setøízená. To znamená, ¾e chceme udr¾ovat mno¾inu $X$ prvkù z lineárnì uspoøádaného universa $U$ s operacemi Find (najdi prvek), Insert (vlo¾ prvek), Delete (sma¾ prvek). K tomu se nám bude hodit reprezentace dat pomocí stromu.
+
+\s{Definice:} {\sc Binární strom} je zakoøenìný strom; ka¾dý vrchol má max. 2 syny, pravého a levého.
+
+Dále budeme pou¾ívat toto znaèení:
+$v$ ... vrchol
+$l(v)$ ... levý syn, $p(v)$ ... pravý syn
+$L(v)$ ... levý podstrom, $p(v)$ ... pravý podstrom
+$T(v)$ ... podstrom s koøenem $v$.
+
+\s{Definice:} {\sc Binární vyhledávací strom} je takový binární strom, ¾e ka¾dý vrchol obsahuje prvek z $U$
+a pro $ \forall v: \forall x \in L(v): x < v,  \forall x \in P(v): x > v $.
+
+\s{Find($T(v)$,$x$)}
+Procházíme strom od koøene, na ka¾dém vrcholu se podle hodnoty $x$ rozhodneme jak budeme pokraèovat. Buï se hodnota vrcholu rovná $x$, pak konèíme (nalezli jsme hledaný prvek). V opaèném pøípadì pokraèujeme v hledání v levém podstromu ($x$ je men¹í ne¾ hodnota vrcholu), nebo v pravém podstromu ($x$ je vìt¹í ne¾ hodnota vrcholu). Pokud dojdeme do listu a prvek jsme nena¹li, znamená to ¾e tento prvek ve stromì není.
+Toto nám zabere $\O($Hloubka stromu$)$.
+
+\s{Insert($T(v)$,$x$)}
+Nejprve najdeme místo kam je potøeba prvek vlo¾it, k tomu pou¾ijeme operaci Find. Pokud Find najde $x$ neprovedeme nic (máme strom s jedineènými hodnotami). Jinak vlo¾íme prvek na místo, kde by mìl být (jako syna vrcholu ve kterém skonèil Find).
+Nejslo¾itìj¹í je operace Find, která trvá $\O($Hloubka stromu$)$.
+
+\s{Min($T(v)$)}
+Minimum se nachází v nejlevìj¹ím listu stromu. Jdeme tedy z koøene poøád doleva, dokud nenarazíme na list.
+Èasová slo¾itost je $\O($hloubka stromu$)$.
+
+\s{Delete($T(v)$,$x$)}
+Opìt pou¾ijeme Find, zjistíme zda prvek vùbec existuje a kde se nachází. Pokud existuje mù¾ou nastat tyto pøípady:
+% FIXME nevim jak presne by mel byt list
+\itemize\ibull
+\next $x$ je list: Prostì ho sma¾eme.
+\next $x$ má jednoho syna: Zru¹íme $x$ a syna pøipojíme na uzel, který ukazoval na $x$.
+\next $x$ má dva syny: Najdeme minimum $P(v)$, toto minimum pøehodíme s $x$ a $x$ sma¾eme.
+\endlist
+Èas je tentokrát malièko slo¾itìj¹í, Find nám trvá $\O($Hloubka stromu$)$ a v posledním pøípadì nalezení Min($P(v)$) trvá taky a¾ $\O($Hloubka stromu$)$, co¾ nám dohromady dává pìkných $\O($Hloubka stromu$)$.
+
+Strom se mù¾e pou¾íváním operací "kazit", napø. opakováním Insert na max. hodnotu co¾ vede a¾ k hloubce $\sim n$. Mù¾eme
+% FIXME nevim jak presne by mel byt list
+\itemize\ibull
+\next vyka¹lat se na to $\rightarrow$ potøeba dokázat prùmìrný pøípad
+\next vylep¹it Insert a Delete $\rightarrow$ vyva¾ování stromù
+\endlist
+
+\h{Vyvá¾ené vyhledávací stromy}
+
+Pøi vyva¾ování si musíme polo¾it cíl, èeho by jsme chteli dosahnout. Vhodné by bylo, aby stromu zùstala logaritmická hloubka a my se u toho moc nenadøeli. Hloubku stromu budeme znaèit $h$.
+
+\s{Definice:} {\sc Dokonale vyvá¾ení} je takové vyvá¾ení, kde platí $ \forall v: \left \| \|L(v)\| - \|P(v)\| \right \| \leq 1 $
+
+Toto nám jistì zaji¹»uje logaritmickou hloubku, ale je velmi pracné na udr¾ování.
+
+\s{Definice:} {\sc Hloubkové vyvá¾ení} je takové vyvá¾ení, kde platí $ \forall v: \left \| h(L(v)) - h(P(v)) \right \| \leq 1 $
+
+Stromùm s hloubkovým vyvá¾ením se øíká AVL stromy. A o nich si doká¾eme následující lemma.
+
+\s{Lemma: } AVL strom o $n$ vrcholech má hloubku $ \O(\log{n}) $.
+\proof
+Uva¾me $a_k = min \{ \forall \| \{ \forall v: h(v) = k \} \| \} $
+
+Lehce spoèteme:
+
+% FIXME neni spravne a chova se divne
+\itemize\ibull
+\next $ a_0 = 0 $
+
+\next $ a_1 = 1 $
+
+\next $ a_2 = 2 $
+
+\next $ \vdots $
+
+\next $ a_k = 1 + a_{k - 1} + a_{k - 2} $
+
+\endlist
+
+Indukcí doká¾eme, ¾e $ a_k \geq 2^{k \over 2} $.
+První indukèní krok jsme si u¾ ukázali, teï pro $ k \geq 2 $ platí:
+$ a_k = 1 + a_{k - 1} + a_{k - 2} - 1 > 2^{{k - 1} \over 2} + 2^{{k - 2} \over 2} = 2^{k \over 2} * (2^{-1 \over 2} + 2^{-1}) > 2^{k \over 2} $
+
+Tímto jsme dokázali, ¾e na ka¾dé hladinì je minimálnì exponenciálnì vrcholù, co¾ nám zaruèuje hloubku $ \O(\log{n})$
+
+\qed
+
+\bye
diff --git a/6-trideni/Makefile b/6-trideni/Makefile
new file mode 100644 (file)
index 0000000..243168f
--- /dev/null
@@ -0,0 +1,3 @@
+P=6-trideni
+
+include ../Makerules
index 1c7ca857c9088ed10172be97ac7fd348ce6e61bb..ad9f853857fe736b21dbf4191aad4b22169e0e26 100644 (file)
@@ -1,5 +1,5 @@
 P=ads
-X:=$(shell for a in 1 2 3 4 ; do echo ../$$a-*/$$a-*.tex ; done)
+X:=$(shell for a in 1 2 3 4 ; do echo ../$$a-*/$$a-*.tex ; done)
 
 %universe: all ChangeLog