From: Martin Mares Date: Tue, 19 Dec 2006 17:25:01 +0000 (+0100) Subject: Reworked. X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=5572db491374defbf0c17cbb664b57226b270f41;p=ga.git Reworked. --- diff --git a/9-suffix/9-suffix.tex b/9-suffix/9-suffix.tex index 1d0d024..e375140 100644 --- a/9-suffix/9-suffix.tex +++ b/9-suffix/9-suffix.tex @@ -1,38 +1,44 @@ \input ../sgr.tex -\def\leaderfill{\leaders\hbox to .5em{\hss.\hss}\hfill} -\def\itemitemitem{\par\indent\indent \hangindent3\parindent \textindent} -\dimen0 = \hsize -\divide \dimen0 by 6 -\def\vs#1#2{#1~{\rm vs.}~#2} - \prednaska{9}{Suffixové stromy} {Tomá¹ Mikula \& Jan Král} -\s {Definícia:} -\+\indent&\hbox to \dimen0 {$\Sigma$\leaderfill}&koneèná abeceda (mno¾ina znakov)\cr -\+&$\Sigma^*$\leaderfill&mno¾ina v¹etkých slov nad $\Sigma$\cr -\+&$\epsilon$\leaderfill&prázdne slovo\cr -\+&$\alpha\beta$\leaderfill&zre»azenie slov $\alpha,\beta\in\Sigma^*$\cr -\+&$\alpha^n$\leaderfill&$n=0: \alpha^0=\epsilon$\cr -\+&&$n>0: \alpha^n=\alpha\alpha^{n-1}$\cr -\+&$\alpha^{\rm R}$\leaderfill&slovo $\alpha$ odzadu\cr -\settabs\+\indent&$\alpha$ je {\it (vlastným) podslovom} $\beta$ &\cr -\+&$\alpha$ je {\it (vlastným) prefixom} $\beta$ &$\equiv \exists\gamma(\not=\epsilon):\beta=\alpha\gamma$\cr -\+&$\alpha$ je {\it (vlastným) sufixom} $\beta$ &$\equiv \exists\gamma(\not=\epsilon):\beta=\gamma\alpha$\cr -\+&$\alpha$ je {\it (vlastným) podslovom} $\beta$ &$\equiv \alpha$ je prefixom nejakého sufixu $\beta$ (a $\alpha\not=\beta$)\cr +V~této kapitole popí¹eme jednu datovou strukturu, pomocí které doká¾eme problémy týkající +se øetìzcù pøevádìt na grafové problémy a tak je øe¹it v~lineárním èase. + +\h{Øetìzce, trie a suffixové stromy} + +\s{Definice:} + +\nointerlineskip +\halign{\qquad#\dotfill&~#\hfil\cr +\hbox to 0.3\hsize{}\cr +$\Sigma$ & koneèná abeceda (mno¾ina znakù, budeme je znaèit latinskými písmeny)\cr +$\Sigma^*$ & mno¾ina v¹ech slov nad $\Sigma$ (slova budeme znaèit øeckými písmeny)\cr +$\varepsilon$ & prázdné slovo\cr +$\vert\alpha\vert$ & délka slova $\alpha$\cr +$\alpha\beta$ & zøetìzení slov $\alpha$ a $\beta$ ($\alpha\varepsilon=\varepsilon\alpha=\alpha$)\cr +$\alpha^R$ & slovo $\alpha$ napsané pozpátku\cr +$\alpha$ je {\I prefixem} $\beta$ & $\exists\gamma: \beta=\alpha\gamma$ ($\beta$ zaèíná na~$\alpha$)\cr +$\alpha$ je {\I suffixem} $\beta$ & $\exists\gamma: \beta=\gamma\alpha$ ($\beta$ konèí na~$\alpha$)\cr +$\alpha$ je {\I podslovem} $\beta$ & $\exists\gamma,\delta: \beta=\gamma\alpha\delta$ (znaèíme $\alpha \subset \beta$)\cr +$\alpha$ je {\I vlastním prefixem} $\beta$ & je prefixem a $\alpha\ne\beta$ (analogicky vlastní suffix a podslovo)\cr +} -\h{Trie} -\s{Definícia:} {\it Trie ($\Sigma$-strom)} pre $X\subset\Sigma^*, \vert X\vert<\infty$ je orientovaný graf $G(V,E)$:\par -$V = \lbrace\alpha\vert\alpha\hbox{ je prefixom nejakého }\beta\in X\rbrace$\par -$(\alpha,\beta)\in E \equiv \exists x\in\Sigma:\beta=\alpha x$\par +\s{Pozorování:} Prázdné slovo je prefixem, suffixem i podslovem ka¾dého slova vèetnì sebe sama. +Podslova jsou právì prefixy suffixù a také suffixy prefixù. -\s{Pozorovanie:} Trie je strom s koreòom $\epsilon$. Listy sú slová z $X$, ktoré nie sú vlastným prefixom iných slov z $X$. +\s{Definice:} {\I Trie ($\Sigma$-strom)} pro koneènou $X\subset\Sigma^*$ je orientovaný graf $G=(V,E)$, kde: +\itemize\relax +\:$V = \{\alpha: \alpha\hbox{ je prefixem nìjakého $\beta\in X$} \},$ +\:$(\alpha,\beta)\in E \equiv \exists x\in\Sigma: \beta=\alpha x$. +\endlist -\s{Definícia:} {\it Komprimovaná trie ($\Sigma^+$-strom)} vznikne z trie nahradením nevetviacich sa ciest hranami (oznaèenými zre»azením znakov príslu¹nej cesty). +\s{Pozorování:} Trie je strom s koøenem $\varepsilon$. Jeho listy jsou slova z $X$, která nejsou vlastním prefixem jiných slov z~$X$. +Hrany si mù¾eme pøedstavit popsané písmeny, o~nì¾ prefix roz¹iøují, popisky hran na~cestì z~koøene do~vrcholu~$\alpha$ dají právì slovo~$\alpha$. -Vrcholom, ktoré padli za obe» kompresii budeme hovori» {\it skryté vrcholy}.\par -Mô¾e sa sta», ¾e nejakému slovu z $X$ odpovedá skrytý vrchol. Aby sme sa tomuto vyhli, pridáme na koniec ka¾dého slova ¹peciálny znak $\$\notin\Sigma$. Teraz platí\par -\s{Pozorovanie:} Listy (komprimovanej) trie sú práve slová z $X$. +\s{Definice:} {\I Komprimovaná trie ($\Sigma^+$-strom)} vznikne z trie nahrazením maximálních nevìtvících se cest hranami. Hrany +jsou tentokrát popsané øetìzci místo jednotlivými písmeny, pøièem¾ popisky v¹ech hrany vycházející z~jednoho vrcholu se li¹í v~prvním +znaku. Vrcholùm \uv{uvnitø hran} (které padly za obìt kompresi) budeme øíkat {\I skryté vrcholy.} \tabskip=0pt plus 1fil \halign to\hsize{ @@ -42,150 +48,201 @@ Trie pre $\{\hbox{AULA, AUTO, AUTOBUS, BUS}\}$ & \dots komprimovan } \smallskip -\h{Sufixové stromy} -\s{Definícia:} {\it Sufixový strom} pre slovo $\sigma\in\Sigma^*$ je komprimovaná trie pre $X=\lbrace {\rm sufixy~}\sigma\rbrace$. +\s{Definice:} {\I Suffixový strom (ST)} pro slovo $\sigma\in\Sigma^*$ je komprimovaná trie pro $X=\{\alpha: \hbox{$\alpha$ je suffixem $\sigma$}\}$. -\s{Pozorovanie:} Listy sú sufixy $\sigma$, ktoré nie sú prefixom iného sufixu. Po pridaní znaku \$ na koniec ka¾dého sufixu sú listy práve v¹etky sufixy. Vnútorné vrcholy sú {\it vetviace podslová} $\sigma$ (tj. $\alpha$ podslová $\sigma$, ktoré sú prefixom aspoò dvoch sufixov a $\alpha x$ je prefixom men¹ieho poètu sufixov pre ka¾dé $x\in\Sigma$). +\s{Pozorování:} Vrcholy suffixového stromu (vèetnì skrytých) odpovídají prefixùm suffixù slova~$\sigma$, +tedy v¹em jeho podslovùm. Listy stromu jsou suffixy, které se v~$\sigma$ ji¾ nikde jinde nevyskytují +(takovým suffixùm budeme øíkat {\I nevnoøené}). Vnitøní vrcholy odpovídají {\I vìtvícím podslovùm,} +tedy podslovùm $\alpha\subset\sigma$ takovým, ¾e $\alpha a\subset\sigma$ i $\alpha b\subset\sigma$ +pro nìjaké dva rùzné znaky~$a$,~$b$. -V listoch si budeme znaèi» index do $\sigma$, kde daný sufix zaèína. +Nìkdy mù¾e být nepraktické, ¾e nìkteré suffixy neodpovídají listùm (proto¾e jsou vnoøené), ale +s~tím se mù¾eme snadno vypoøádat: pøidáme na~konec slova~$\sigma$ nìjaký znak~$\$$, který se nikde +jinde nevyskytuje. Suffixy slova $\sigma\$$ odpovídají suffixùm slova~$\sigma$ (kdy¾ pomineme +prázdný suffix) a ¾ádný z~nich nemù¾e být vnoøený. \figure{st-barbara.eps}{Sufixový strom pre slovo BARBARA}{0pt} -\s{Lemma:} Sufixový strom pre slovo $\sigma$ då¾ky $n$ je reprezentovateµný v priestore $\O(n)$.\par -\s{Dôkaz:} Strom má $\O(n)$ listov a ka¾dý vnútorný vrchol má výstupný stupeò aspoò $2$ a teda v¹etkých vrcholov je $\O(n)$. Keï¾e sa jedná o strom, hrán je tie¾ len $\O(n)$. Nálepky na hranách budú reprezentované ako 2 indexy do $\sigma$ oznaèujúce zaèiatok a koniec nejakého úseku odpovedajúceho písmenkám na hrane.\qed - -\s{Veta:} Sufixový strom pre slovo då¾ky $n$ sa dá zostroji» v èase $\O(n)$.\par -\s{Dôkaz:} Budú uvedené 2 kon¹trukcie v lineárnom èase.\qed - -\s{Aplikácie} (alebo èo doká¾eme v èase $\O(n)$):\par -\item{1.} inverzné vyhµadávanie (tj. vyhµadávanie µubovoµného výrazu v predspracovanom texte (nie predspracovaného výrazu (napr. koneèný automat) v µubovoµnom texte)) -\itemitem{-}v¹etky výskyty; ak u¾ máme strom postavený, doká¾eme nájs» v¹etkých $k$ výskytov podslova då¾ky $m$ v èase $\O(m+k)$ (vo vnútorných vrcholoch si budeme naviac udr¾iava» pointre na lexikograficky najmen¹í a najväè¹í list podstromu a v listoch pointer na ïal¹í list v lex. poradí) -\itemitem{-}poèet výskytov (v ka¾dom vnútornom vrchole budeme ma» predpoèítaný poèet listov, ktoré sa pod ním nachádzajú) -\item{2.} najdlh¹ie opakujúce sa podslovo -\itemitem{$\cong$} najhlb¹ie vetvenie (písmenkovo najhlb¹í vnútorný vrchol) -\item{3.} histogram $k$-podslov (èetnos» slov då¾ky $k$) -\itemitem{-} odre¾eme strom v písmenkovej håbke $k$ a spoèítame odrezané vetvièky -\item{4.}najdlh¹í spoloèný podre»azec slov $\alpha$ a $\beta$ ($LCS(\alpha, \beta)$) -\itemitem{-}postavíme strom pre slovo $\alpha\$_1\beta\$_2$; najhlb¹í vrchol, pod ktorým je $\alpha$-ový i $\beta$-ový sufix ($\$_1$ i $\$_2$) odpovedá $LCS(\alpha,\beta)$ -\item{5.}najdlh¹ie palindromické podslovo ($\beta$ je palindromické $\equiv \beta = \beta^{\rm R}$) -\itemitem{-} Postavíme sufixový strom pre $\alpha\$_1\alpha^R\$_2$. Postupne prechádzame cez v¹etky potenciálne stredy palindromu (je ich $2n-1$) a poèítame: -\itemitemitem{$\bullet$}$LCP(\alpha[i:], \alpha^{\rm R}[n-(i+1):])$, keï uva¾ujeme ako stred palindromu $i$-té písmenko (èíslované od 0) (tj. palindrom nepárnej då¾ky) -\itemitemitem{$\bullet$}$LCP(\alpha[i+1:], \alpha^{\rm R}[n-(i+1)])$, keï uva¾ujeme stred palindromu medzi $i$-tým a $(i+1)$-vým písmenkom (tj. palindrom párnej då¾ky). -\itemitem{}$LCP(\alpha,\beta)$ je najdlh¹í spoloèný prefix $\alpha$ a $\beta$ a v strome je to najhlb¹í spoloèný predchodca ($LCA$) listov odpovedajúcich $\alpha$ a $\beta$. -\itemitem{}Pritom treba ¹ikovne liez» po strome, aby nájdenie ïal¹ej odpovedajúcej si dvojice listov bolo kon¹tantné. -\itemitem{}Na nájdenie $LCA$ pou¾ijeme nejakú ¹truktúru, ktorá to po lineárnom predvýpoète zvládne v kon¹tantnom èase. -\item{6.}Burrows-Wheeler transform (BWT) - -\h{Rekurzívna kon¹trukcia sufixového stromu v lineárnom èase} -\s{Definícia:} {\it Suffix Array} $A$ pre slovo $\sigma$ je permutácia na sufixoch slova $\sigma$, ktorá ich zotriedi lexikograficky:\hfil\break -$\sigma[A[i]:]<_{lex}\sigma[A[i+1]:]$, kde $\sigma[j:]$ znaèí podslovo $\sigma$ poènúc $j$-tým písmenkom a¾ do konca. - -\s{Definícia:} {\it LCP Array} $L$ pre slovo $\sigma$:\hfil\break -$L[i]=\vert LCP(\sigma[A[i]:], \sigma[A[i+1]:])\vert$, kde $LCP(\alpha, \beta)$ je najdlh¹í spoloèný prefix $\alpha$ a $\beta$. - -\s{Definícia:} {\it Kartézsky strom} pre postupnos» kµúèov $x_1\ldots x_n$ je strom, ktorý je haldou podµa hodnôt kµúèov a vyhµadávacím stromom podµa poradia kµúèov v postupnosti. Pritom vrcholy s rovnakou hodnotou, ktoré by spolu susedili, zlúèime do jedného. - -Niektoré vrcholy majú voµné miesta, kde by mohol by» pripojený podstrom. Týmto voµným miestam budeme hovori» {\it voµné sloty}. +\s{Lemma:} Suffixový strom pro slovo $\sigma$ délky $n$ je reprezentovatelný v~prostoru $\O(n)$. -\tabskip=0pt plus 1fil -\halign to\hsize{ -\hfil#\hfil&\hfil#\hfil\cr -\epsfbox{ct-35120024224.eps}&\epsfbox{ct-35120024224-fs.eps}\cr -Kartézsky strom pre $(3,5,1,2,0,0,2,4,2,2,4)$ & \dots s vyznaèenými voµnými slotmi\cr -} -\smallskip +\s{Dùkaz:} Strom má $\O(n)$ listù a ka¾dý vnitøní vrchol má alespoò $2$ syny, tak¾e vnitøních +vrcholù je také $\O(n)$. Hran je rovnì¾ lineárnì. Nálepky na~hranách si staèí reprezentovat +poèáteèní a koncovou pozicí v~$\sigma$. +\qed + +\s{Vìta:} Suffixový strom pro slovo $\sigma$ délky $n$ lze sestrojit v~èase $\O(n)$. + +\s{Dùkaz:} Ve~zbytku této kapitoly pøedvedeme dvì rùzné konstrukce v~lineárním èase. +\qed + +\s{Aplikace:} (co v¹e doká¾eme v~lineárním èase, kdy¾ umíme lineárnì konstruovat ST) + +\numlist\ndotted +\:{\I Inverzní vyhledávání} (tj. pøedzpracujeme si v~lineárním èase text a pak umíme pro libovolné +slovo~$\alpha$ v~èase $\O(\vert\alpha\vert)$ rozhodnout, zda se v~textu vyskytuje.\foot{Èili pøesný +opak toho, co~umí vyhledávací automat -- ten si pøedzpracovává dotaz.} -- staèí sestrojit~ST +a pak jej procházet od~koøene. Také umíme najít v¹echny výskyty (odpovídají suffixùm, které mají +jako prefix hledané slovo, tak¾e staèí vytvoøit ST s~dolarem a vypsat v¹echny listy pod +nalezeným vrcholem) nebo pøímo vrátit jejich poèet (pøedpoèítáme si pomocí DFS pro ka¾dý vrchol, +kolik pod ním le¾í listù). + +\:{\I Nejdel¹í opakující se podslovo} -- takové podslovo je nutnì vìtvící, tak¾e staèí +najít vnitøní vrchol s~nejvìt¹í {\I písmenkovou hloubkou} (tj. hloubkou mìøenou ve~znacích +místo ve~hranách). + +\:{\I Histogram èetností podslov délky~$k$} -- rozøízneme ST v~písmenkové hloubce~$k$ a spoèítáme, +kolik pùvodních listù je pod ka¾dým novým. + +\:{\I Nejdel¹í spoleèné podslovo} slov~$\alpha$ a $\beta$ -- postavíme ST pro slovo $\alpha\$_1\beta\$_2$, +jeho listy odpovídají suffixùm slov $\alpha$ a $\beta$. Tak¾e staèí pomocí DFS najít nejhlub¹í vnitøní +vrchol, pod kterým se vyskytují listy pro~$\alpha$ i $\beta$. Podobnì mù¾eme sestrojit ST pro libovolnou +mno¾inu slov.\foot{Jen si musíme dát pozor, abychom si moc nezvìt¹ili abecedu, ale to bude jasné, +a¾ pøedvedeme konkrétní konstrukce.} + +\:{\I Nejdel¹í palindromické podslovo} (tj. takové $\beta\subset\alpha$, pro nì¾ je $\beta_R=\beta$) +-- postavíme spoleèný ST pro slova $\alpha$ a $\alpha_R$. Postupnì procházíme pøes v¹echny mo¾né støedy +palindromického podslova a v¹imneme si, ¾e takové slovo je pro ka¾dý støed nejdel¹ím spoleèným +prefixem podslova od~tohoto bodu do~konce a podslova od~tohoto bodu (pozpátku) k~zaèátku, +èili nìjakého suffixu $\alpha$ a nìjakého suffixu $\alpha_R$. Tyto suffixy ov¹em odpovídají +listùm sestrojeného ST a jejich nejdel¹í spoleèný prefix je nejbli¾¹ím spoleèným pøedchùdcem +ve~stromu, tak¾e staèí pro strom vybudovat datovou strukturu pro spoleèné pøedchùdce +a s~její pomocí doká¾eme jeden støed prozkoumat v~konstantním èase. + +\:{\I Burrows-Wheelerova Transformace} -- jejím základem je lexikografické setøidìní v¹ech +rotací slova~$\sigma$, co¾ zvládneme sestrojením ST pro slovo~$\sigma\sigma$, jeho +uøíznutím v~písmenkové hloubce~$\vert\sigma\vert$ a následným vypsáním listù v~poøadí dle~DFS. +\endlist + +\h{Suffix Array} + +\>V~nìkterých pøípadech se hodí místo suffixového stromu pou¾ívat kompaktnìj¹í datové struktury. -\s{Lemma:} Kartézsky strom pre $x_1\ldots x_n$ sa dá postavi» v èase $\O(n)$.\qed -\s{Lemma:} Sufixový strom (ST) pre $\sigma$ a $(A,L)$ pre $\sigma$ sú lineárne izomorfné.\par -\s{Dôkaz:}\par -${\rm ST}\longrightarrow(A,L)$: -\itemitem{}Prechádzame strom zµava doprava (tj. lexikograficky). V¾dy, keï sme v liste, opí¹eme do $A[i]$ index do $\sigma$, ktorý sme v liste na¹li; $i$ inicializujeme na $-1$ a pri ka¾dej náv¹teve listu zväè¹ujeme o $1$ (e¹te pred zápisom do $A[i]$). -\itemitem{}Medzi náv¹tevou 2 susedných listov v¾dy najskôr stúpame a potom sa znova ponoríme. Najvy¹¹í vrchol, po ktorý sme vystúpili medzi náv¹tevou listov $\alpha$ a $\beta$, odpovedá $LCP(\alpha,\beta)$, jeho håbka odpovedá $\vert LCP(\alpha, \beta)\vert$. Do $L[i]$ teda zapí¹eme håbku tohto najhlb¹ieho spoloèného predka, ktorú si poèítame v rekurzii. +\s{Notace:} Pro slovo $\sigma$ bude $\sigma[i:j]$ znaèit podslovo slo¾ené z~$i$-tého a¾ $j$-tého +znaku slova~$\sigma$ (znaky èíslujeme od~$1$). Navíc $\sigma[i:{}]$ bude suffix od~$i$ do~konce +a $\sigma[{}:j]$ prefix od~zaèátku do~$j$. Prázdný suffix mù¾eme znaèit jako $\sigma[\vert\sigma\vert+1:{}].$ -$(A,L)\longrightarrow{\rm ST}$: -\itemitem{}Staviame kartézsky strom pre $L$ a do voµných slotov privesujeme listy. Tento strom má tvar sufixového stromu pre $\sigma$. Indexy v listoch urèujeme podµa $A$. Nálepky na hranách urèujeme podµa indexov v listoch podstromu a (písmenkovej) håbky vrcholov (ktorú pre vnútorné vrcholy máme v $L$ a pre listy vypoèítame ako $\vert\sigma\vert - A[i]$).\qed +\s{Definice:} {\I Suffix Array} $A_\sigma$ pro slovo $\sigma$ délky~$n$ je posloupnost v¹ech suffixù +slova~$\sigma$ v~lexikografickém poøadí. Mù¾eme ho reprezentovat napøíklad jako permutaci $A$ èísel +$1,\ldots,n+1$, pro ní¾ $\sigma[A[1]:{}] < \sigma[A[2]:{}] < \ldots < \sigma[A[n+1]:]$. -\medskip -Ná¹ algoritmus bude kon¹truova» $(A,L)$, ktoré u¾ teraz vieme v lineárnom èase previes» na sufixový strom. +\s{Definice:} {\I Longest Common Prefix Array} $L_\sigma$ pro slovo $\sigma$ je posloupnost, +v~ní¾ $L_\sigma[i]$ udává délku nejdel¹ího spoleèného prefixu slov $A_\sigma[i]$ a $A_\sigma[i+1]$. + +\s{Vìta:} Suffixový strom pro slovo $\sigma$ s~dolarem je lineárnì ekvivalentní s~dvojicí $(A_\sigma,L_\sigma)$. +[Jinými slovy, kdy¾ máme jedno, mu¾eme z~toho v~lineárním èase spoèítat druhé a naopak.] + +\s{Dùkaz:} Kdy¾ projdeme ST($\sigma$) do hloubky, poøadí listù odpovídá $A_\sigma$ a písmenkové hloubky vnitøních +vrcholù v~inorderu odpovídají $L_\sigma$. Naopak ST($\sigma$) získáme tak, ¾e sestrojíme kartézský strom +pro~$L_\sigma$ (to jsou vnitøní vrcholy ST), doplníme do~nìj listy a pøiøadíme jim suffixy podle~$A_\sigma$ +a nakonec podle listù rekonstruujeme nálepky hran. + +\h{Rekurzivní konstrukce} + +\>Tento algoritmus konstruuje pro slovo $\sigma$ délky~$n$ pole $A_\sigma$ a $L_\sigma$ v~èase $\O(n+{\rm Sort}(n,\Sigma))$, +kde ${\rm Sort}(\ldots)$ je èas potøebný pro setøídìní $n$ symbolù z~abecedy~$\Sigma$. V~kombinaci s~pøedchozími +výsledky nám tedy dává lineární konstrukci ST($\sigma$) pro libovolnou fixní abecedu. + +\s{Algoritmus:} (Konstrukce $A$ a $L$ podle Kärkkäinena a Sanderse) \algo -\:(Z abecedy vyhodíme nepou¾ité znaky.) -\itemitem{}Pou¾ité znaky zotriedime priehradkovým triedením v èase $\O(n)$ a premenujeme na $1,\ldots,n'$, $n'\le n$. +\:Redukujeme abecedu na~$1\ldots n$: ve~vstupním slovu je nejvý¹e $n$ rùzných znakù, +tak¾e je staèí setøidit a pøeèíslovat. -\:Definujeme slová $\sigma_0$, $\sigma_1$, $\sigma_2$ nasledujúcim spôsobom: -%\settabs\+\itemitemitem{}&$\sigma_2[i] := (\sigma[3i+2],$ &$\sigma[3i+3],$ &$\sigma[3i+4])$\cr +\:Definujeme slova $\sigma_0$, $\sigma_1$, $\sigma_2$ následovnì: $$\eqalign{ -\sigma_0[i] &:= (\sigma[3i],\sigma[3i+1],\sigma[3i+2])\cr -\sigma_1[i] &:= (\sigma[3i+1],\sigma[3i+2],\sigma[3i+3])\cr -\sigma_2[i] &:= (\sigma[3i+2],\sigma[3i+3],\sigma[3i+4])\cr +\sigma_0[i] &:= \left<\sigma[3i],\sigma[3i+1],\sigma[3i+2]\right>\cr +\sigma_1[i] &:= \left<\sigma[3i+1],\sigma[3i+2],\sigma[3i+3]\right>\cr +\sigma_2[i] &:= \left<\sigma[3i+2],\sigma[3i+3],\sigma[3i+4]\right>\cr }$$ -\itemitem{}$\sigma_0$, $\sigma_1$, $\sigma_2$ sú slová då¾ky $\approx{n\over3}$ nad abecedou $[n']^3$. (Opä» ale z nej pou¾ijeme najviac $n$ znakov.) +Slova $\sigma_k$ jsou slova délky $\approx n/3$ nad~abecedou velikosti $n^3$. Dovolíme +si mírnì zneu¾ívat notaci a znaèit $\sigma_k$ i jejich pøepis do~abecedy pùvodní. + +\:Zavoláme se rekurzivnì na slovo $\sigma_0\sigma_1$, èím¾ získáme $A_{01}$ a $L_{01}$. + +\:Z~$A_{01}$ a $L_{01}$ vydìlíme $A_0=A_{\sigma_0}$, $A_1$, $L_0$ a $L_1$ a spoèítáme permutace inverzní k~$A_0$ a $A_1$. -\:Zavoláme sa rekurzívne na $\sigma_0\sigma_1$, získame $(A_{01},L_{01})$. Z $A_{01}$ doká¾eme jedným priechodom vyrobi» $A_0$, $A_1$, $A_{01}^{-1}$. ($A_{01}^{-1}$ je inverzná permutácia k $A_{01}$) +\:Dopoèítáme $A_2$: Jeliko¾ $\sigma_2[i:{}] = \sigma[3i+2:{}] = \sigma[3i+2]\sigma[3i+3:{}] = \sigma[3i+2]\sigma_0[i+1:{}]$ +a v¹echna $\sigma_0[i:{}]$ u¾ máme setøidìná, mù¾eme v¹echna $\sigma_2[i:{}]$ setøídit dvìma prùchody pøíhrádkového tøídìní. -\:Dopoèítame $A_2$.\par -\itemitem{}Vyu¾ijeme, ¾e $\sigma_2[i:]\approx\sigma[3i+2:]=\sigma[3i+2]\sigma[3i+3:]\approx\sigma[3i+2]\sigma_0[i+1:]$. -\itemitem{}Pre slová $\sigma_2[i:]\approx\sigma[3i+2]\sigma_0[i+1:]$ máme usporiadanie podµa druhej èasti (tj. podµa $\sigma_0[i+1:]$) v $A_0$. V tomto poradí ich nahád¾eme do priehradok podµa prvého znaku prvého znaku (tj. podµa $\sigma[3i+2]$) a vysypeme do $A_2$. +\:Dopoèítáme $L_2$: Stejným trikem jako $A_2$ -- pokud jsou první písmena rùzná, je spoleèný prefix prázdný, jinak +má délku $1+{\rm LCP}(\sigma_0[i+1:{}],\sigma_0[j+1:{}]) = \min_{i+1\le k< j+1} L_0[k]$. To zvládneme v~konstantním +èase na~operaci pomoci datové struktuy pro intervalová minima. -\:$A_0,A_1,A_2\buildrel merge\over\longrightarrow A$ -\itemitem{}Nech $a$, $b$, $c$, sú aktuálne pozície v $A_0$, $A_1$, $A_2$ (v tomto poradí) pri zlievaní. Nech $i=A_0[a]$, $j=A_1[b]$, $k=A_2[c]$. Potrebujeme porovna» slová $\sigma_0[i:]$, $\sigma_1[j:]$, $\sigma_2[k:]$ v kon¹tantnom èase. +\:$A_0,A_1,A_2\buildrel merge\over\longrightarrow A$ -- sléváme tøi setøidìné posloupnosti, +tak¾e staèí umìt prvky libovolných dvou posloupností v~konstantním èase porovnat: $$\eqalign{ -\sigma_0[i:] < \sigma_1[j:] &\equiv A_{01}^{-1}[i] < A_{01}^{-1}[\vert\sigma_0\vert+j]\cr -\sigma_0[i:] < \sigma_2[k:] &\equiv \sigma[3i]\,\sigma_1[i:] < \sigma[3k+2]\,\sigma_0[k+1:]\cr -&\Leftrightarrow (\sigma[3i] < \sigma[3k+2]) \vee (\sigma[3i] = \sigma[3k+2] \wedge \sigma_1[i:] < \sigma_0[k+1:])\cr -\sigma_1[j:]<\sigma_2[k:] &\equiv \sigma[3j+1]\,\sigma[3j+2]\,\sigma_0[j+1:] < \sigma[3k+2]\,\sigma[3k+3]\,\sigma_1[k+1:] +\sigma_0[i:{}] < \sigma_1[j:{}] &\equiv A_{01}^{-1}[i] < A_{01}^{-1}[\vert\sigma_0\vert+j]\cr +\sigma_0[i:{}] < \sigma_2[k:{}] &\equiv \sigma[3i]\,\sigma_1[i:{}] < \sigma[3k+2]\,\sigma_0[k+1:{}]\cr +&\Leftrightarrow (\sigma[3i] < \sigma[3k+2]) \vee (\sigma[3i] = \sigma[3k+2] \wedge \sigma_1[i:{}] < \sigma_0[k+1:{}])\cr +\sigma_1[j:{}]<\sigma_2[k:{}] &\equiv \sigma[3j+1]\,\sigma[3j+2]\,\sigma_0[j+1:{}] < \sigma[3k+2]\,\sigma[3k+3]\,\sigma_1[k+1:{}] }$$ -\:Dopoèítame $L$. -\itemitem{} Pripomeòme definíciu $L[i]=\vert LCP(\sigma[A[i]:], \sigma[A[i+1]:])\vert$. -\itemitem{} Nech -\tabskip=3\parindent -\halign{\hfil#\tabskip=0pt&#\hfil&#\hfil\cr -$\sigma[A[i]:]$ &$\approx \sigma_0[j:]$,\quad&tj. $A[i]=3j$ pre nejaké $j$,\cr -$\sigma[A[i+1]:]$ &$\approx \sigma_0[k:]$,&tj. $A[i+1]=3k$ pre nejaké $k$.\cr -} -\itemitem{} Oznaème tento prípad $\vs{\sigma_0}{\sigma_0}$. Potom $L[i]=L_{01}[A_{01}^{-1}[A[i] \div 3]]$. -\itemitem{} Prípad $\vs{\sigma_0}{\sigma_1}$ vyrie¹ime rovnako. -\itemitem{} Prípady $\vs{\sigma_1}{\sigma_0}$ a $\vs{\sigma_1}{\sigma_1}$: $L[i]=L_{01}[A_{01}^{-1}[A[i] \div 3 + \vert\sigma_0\vert]]$ -\+\cleartabs\itemitem{} &$\vs{\sigma_2}{\sigma_2}$: &a$)$ lí¹ia sa prvým znakom $\Rightarrow L[i]=0$\cr -\+&&b$)$ $L[i]=1+(\vs{\sigma_0}{\sigma_0})$\cr -\+&$\vs{\sigma_2}{\sigma_0}$: &a$)$ lí¹ia sa prvým znakom $\Rightarrow L[i]=0$\cr -\+&&b$)$ $L[i]=1+(\vs{\sigma_0}{\sigma_1})$\cr -\+&$\vs{\sigma_2}{\sigma_1}$: &a$)$ lí¹ia sa prvým znakom $\Rightarrow L[i]=0$\cr -\+&&b$)$ lí¹ia sa druhým znakom $\Rightarrow L[i]=1$\cr -\+&&c$)$ $L[i]=2+(\vs{\sigma_1}{\sigma_0})$\cr +\:Dopoèítame $L$ -- pokud sousedí suffix ze~$\sigma_{0,1}$ se suffixem ze~$\sigma{0,1}$, +vyèteme výsledek pøímo z~$L_{01}$. Pokud sousedí $\sigma_2$ se $\sigma_2$, staèí pou¾ít +u¾ spoèítané $L_2$. Pokud sousedí $\sigma_{0,1}$ se $\sigma_2$, odebereme první jeden +nebo dva znaky, ty porovnáme samostatnì a v~pøípadì shody zbude suffix ze~$\sigma_0$ +a suffix ze~$\sigma_1$ (stejnì jako pøi slévání) a pro ty doká¾eme $L$ dopoèítat +pomocí struktury pro intervalová minima v~$L_01$. \endalgo -\s{Odhad èasovej zlo¾itosti}\par -$T(n) = T({2\over3}n) + \O(n) = \O(n)$ +\s{Analýza èasové slo¾itosti:} Tøídìní v~prvním volání trvá ${\rm Sort}(n,\Sigma)$, ve~v¹ech +ostatních voláních je lineární (trojice èísel velikosti $\O(n)$ mù¾eme tøídit tøíprùchodovým +pøíhrádkovým tøídìním s~$\O(n)$ pøíhrádkami). Dostáváme tedy: +$$T(n) = T(2/3\cdot n) + \O(n),~\hbox{a tedy}~T(n)=\O(n).$$ +\qed \h{Ukkonenova inkrementální konstrukce} -Pomocí Ukkonnenovy konstrukce doká¾eme sestrojit suffixový strom v lineárním èase. Algoritmus je navíc inkrementální, v ka¾dém kroku tak ze stávajícího suffixového stromu ($ST$ pro $\sigma$) vyrobí strom odpovídající roz¹íøenému slovu ($\sigma a$). Vychází pøitom ze stromu pro prázdné slovo (prázdný strom), který postupnì roz¹iøuje. +\>Ukkonenùv algoritmus konstruuje suffixový strom bez dolarù inkrementálnì: zaène se stromem +pro prázdné slovo (ten má jediný vrchol, a to koøen) a postupnì pøidává dal¹í znaky na~konec +slova. To zvládne v~èase $\O(1)$ amortizovanì na~pøidání jednoho znaku. +Pro slovo~$\sigma$ tedy doká¾e sestrojit ST v~èase $\O(\vert\sigma\vert)$. -Roz¹íøení suffixového stromu doká¾e algoritmus provést v amortizovanì konstantním èase. +\s{Pozorování:} Kdy¾ slovo~$\sigma$ roz¹íøíme na~$\sigma a$, ST se zmìní následovnì: -\s{Pozorování:}Následující pozorování platí pro roz¹iøování suffixového stromu pro $\sigma$ na suffixový strom pro $\sigma a$: \numlist\ndotted -\:Pokud bylo slovo vìtvící v $\sigma$, pak bude stale vìtvící -\:Pokud byl uzel nevnoøený, bude stále nevnoøený -\:listy zùstávají jako listy (musím na hranu, ktera do nìj vede pøipsat $a$) -- øe¹íme otevøenými hranami (ne nálepka odsud sem, ale odsud dokonce) - slo¾itost - $O(0)$ -\:vnitøní vrcholy $\to$ vnitøní vrcholy -\:Mohou vznikat nové vrcholy (listy i vnitøní), slovo nevìtvící se tak mù¾e stát vìtvícím +\:Pokud $\beta$ byl nevnoøený suffix $\sigma$, je i $\beta a$ nevnoøený suffix -- listy +zùstanou listy, pouze jim potøebujeme prodlou¾it nálepky. Pomu¾eme si snadno: zavedeme +{\I otevøené hrany,} jejich¾ nálepka je \uv{od~pozice~$i$ do konce}. Listy se tedy +o~sebe postarají samy. +\:Pokud $\beta$ bylo vìtvící slovo, zùstane nadále vìtvící -- vnitøní vrcholy tedy zùstanou. +\:Pokud $\beta$ byl vnoøený suffix (tj. vnitøní èi skrytý vrchol), je $\beta a$ buïto +také vnoøený (a postará se o~sebe sám), nebo se vùbec nevyskytuje v~$\sigma$ a musíme +pro~nìj zalo¾it novou odboèku a nový list s~otevøenou hranou. \endlist -\s{Definice:Aktivni suffix ($\alpha(\sigma)$)} nazýváme nejdel¹í vnoøený suffix $\sigma$ +\s{Definice:} {\I Aktivní suffix} $\alpha(\sigma)$ øíkáme nejdel¹ímu vnoøenému suffixu slova~$\sigma$. + +\s{Lemma:} Suffix $\beta$ slova $\sigma$ je vnoøený $\Leftrightarrow$ $\vert\beta\vert \le \vert\alpha(\sigma)\vert.$ + +\s{Dùkaz:} Ka¾dý suffix vnoøeného suffixu je opìt vnoøený. \qed + +\s{Lemma:} Pro ka¾dé $\sigma$, $a$ platí: $\alpha(\sigma a)$ je suffixem $\alpha(\sigma)a.$ + +\s{Dùkaz:} $\alpha(\sigma a)$ i $\alpha(\sigma)a$ jsou suffixy slova $\sigma a$, a~proto staèí porovnat jejich délky. +Slovo $\beta := \hbox{$\alpha(\sigma a)$ bez koncového~$a$}$ je vnoøený suffix v~$\sigma$, tak¾e +$\vert\beta\vert \le \vert\alpha(\sigma)\vert$, a~tedy také $\vert\alpha(\sigma a)\vert = \vert\beta a\vert \le \vert\alpha(\sigma)a\vert$. +\qed + +\s{Definice:} Suffix $\beta a$ je {\I zralý} (musíme pro~nìj pøi pøidávání znaku~$a$ k~aktuálnímu +slovu~$\sigma$ zakládat nový vrchol) $\equiv$ $\beta$ je vnoøený suffix~$\sigma$, ale $\beta a$ není podslovem~$\sigma$. + +\s{Lemma:} Suffix $\beta$ je zralý $\Leftrightarrow$ $\vert\alpha(\sigma)a\vert \ge \vert\beta a\vert > \vert\alpha(\sigma a)\vert$. -\s{Lemma:} Pro ka¾dé $\sigma$, $a$ platí: $\alpha(\sigma a)$ je suffixem $\alpha(\sigma)a$ +\s{Dùkaz:} Jeliko¾ $\beta$ je vnoøeným suffixem $\sigma$, musí platit první nerovnost. Aby byl zralý, +musí také nebýt vnoøeným suffixem $\sigma a$, èemu¾ odpovídá druhá nerovnost. +\qed -\s{Dùkaz:} $\alpha(\sigma a)$, $\alpha(\sigma)a$ jsou suffixy $\sigma a$, z toho plyne, ¾e staèí porovnat délky abychom lemma ovìøili. -Platí: $ \vert\alpha(\sigma a)\vert \le \vert\alpha(\sigma)a\vert$ (pøidáním písmene nemù¾u prodlou¾it prefix o více ne¾ jeden znak). +\s{Algoritmus:} Udr¾uji si $\alpha=\alpha(\sigma)$ a pøi pøidání znaku $a$ zkontroluji, zda $\alpha a$ je +stále vnoøený suffix. Pokud ano, nic se nemìní, pokud ne, pøidám vnitøní vrchol, $\alpha$ zkrátím +zleva o~znak a testuji dál. -\s{Definice:Zralé suffixy} jsou ty prefixy $\alpha$, pro ktere platí: -$\forall \sigma, a,\beta: \beta a$ suffix $\sigma a$ je {\it zralý} právì kdy¾ $ \vert\alpha(\sigma)a\vert \ge \vert\beta a\vert > \vert\alpha(\sigma a)\vert$ +\s{Èasová slo¾itost:} Úprav stromu provedu $\O(1)$ amortizovanì (ka¾dá úprava $\alpha$ zkrátí, +ka¾dé pøidání znaku ho~prodlou¾í o~1, tak¾e v¹ech zkrácení je $\O(\vert\sigma\vert)$). Staèí +tedy ukázat, jak provést úpravu v~(amortizovanì) konstantním èase. -Update je $O(1)$ amortizovanì na $1$ roz¹íøení $\sigma$ +\todo{Zbytek dosud nezrevidován.} $\alpha(\sigma)$ reprezentuji jako kanonický (neexistuje jiný referenèní pár s krat¹ím $\alpha$) referenèní pár $(v, \alpha)$ kde $v$ je vrchol $ST$ a $\alpha$ ke cesta kudy dál. @@ -195,12 +252,12 @@ $\alpha(\sigma)$ reprezentuji jako kanonick \:Vstup: $\sigma, a, (v, \alpha)$ // 1. Zalo¾ení listù/Podrozdìlení hran -\:if $\alpha = \epsilon$: +\:if $\alpha = \varepsilon$: \::if $\exists (v, a* )$ \:::konec \::else: \:::zalo¾ím list -\:else if $\alpha \ne \epsilon$: +\:else if $\alpha \ne \varepsilon$: \::if $\exists (v, \alpha a*)$: \:::konec \::else: @@ -208,8 +265,8 @@ $\alpha(\sigma)$ reprezentuji jako kanonick // 2. Pøechod na dal¹í vrchol \:zkrátim $\alpha$ zleva o znak -\:if $v = \epsilon$: -\::pøejdu do $( \epsilon, \alpha bez 1. znaku)$ +\:if $v = \varepsilon$: +\::pøejdu do $( \varepsilon, \alpha bez 1. znaku)$ \:else: \::pøejdu do $( back[v], \alpha )$