From: Martin Mares Date: Fri, 29 Dec 2006 00:20:25 +0000 (+0100) Subject: Finish. X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=e2360a1029eeb061710c1bbcfc015f8aeab13753;p=ga.git Finish. --- diff --git a/9-suffix/9-suffix.tex b/9-suffix/9-suffix.tex index 7045e3e..3841d68 100644 --- a/9-suffix/9-suffix.tex +++ b/9-suffix/9-suffix.tex @@ -37,16 +37,17 @@ Podslova jsou pr 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$. \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 +jsou tentokrát popsané øetìzci místo jednotlivými písmeny, pøièem¾ popisky v¹ech hrany vycházejících 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.} +\medskip \tabskip=0pt plus 1fil \halign to\hsize{ \hfil#\hfil&\hfil#\hfil&\hfil#\hfil\cr \epsfbox{trie.eps}&\epsfbox{trie-c.eps}&\epsfbox{trie-cd.eps}\cr -Trie pre $\{\hbox{AULA, AUTO, AUTOBUS, BUS}\}$ & \dots komprimovaná & \dots odolarovaná\cr +Trie pro $\{\hbox{AULA, AUTO, AUTOBUS, BUS}\}$ & \dots komprimovaná & \dots odolarovaná\cr } -\smallskip +\medskip \s{Definice:} {\I Suffixový strom (ST)} pro slovo $\sigma\in\Sigma^*$ je komprimovaná trie pro $X=\{\alpha: \hbox{$\alpha$ je suffixem $\sigma$}\}$. @@ -61,7 +62,7 @@ s~t 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} +\figure{st-barbara.eps}{Suffixový strom pro slovo BARBARA}{0pt} \s{Lemma:} Suffixový strom pro slovo $\sigma$ délky $n$ je reprezentovatelný v~prostoru $\O(n)$. @@ -108,7 +109,7 @@ list 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 +\:{\I Burrows-Wheelerova Transformace} -- jejím základem je lexikografické setøídì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 @@ -118,15 +119,21 @@ u \>V~nìkterých pøípadech se hodí místo suffixového stromu pou¾ívat kompaktnìj¹í datové struktury. \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:{}].$ +znaku slova~$\sigma$ (znaky èíslujeme od~$1$). Libovolnou z~mezí mù¾eme vynechat, tak¾e +$\sigma[i:{}]$ bude suffix od~$i$ do~konce a $\sigma[{}:j]$ prefix od~zaèátku do~$j$. +Pokud $j[\pi]$ vede z~vrcholu $\pi$ do~vrcholu, +který je ze~v¹ech vrcholù nejdel¹ím vlastním suffixem slova~$\pi$. -\s{Definice: $back[v]$} je nejdel¹í vlastní suffix $v$, ke kterému existuje vrchol. +\s{Pozorování:} Zpìtné hrany jsme sice zavedli stejnì obecnì, jako se to dìlá +pøi konstrukci vyhledávacích automatù podle Aha a McCorasickové, ale v~na¹em +pøípadì se \ pro vnitøní vrcholy chová daleko jednodu¹eji (a~na ¾ádné +jiné ho potøebovat nebudeme): pokud je $\pi$ vnitøní vrchol, musí to být +vìtvící podslovo, a~tím pádem ka¾dé jeho zkrácení zleva musí být také vìtvící +podslovo. Tedy $\(\pi)$ dá~$\pi$ bez prvního znaku, co¾ se nám +bude hodit pøi zkracování suffixù. + +\s{Algoritmus podrobnìji:} (Doplnili jsme detaily do~pøedchozího algoritmu.) \algo -\:Vstup: $\sigma, a, (v, \alpha)$ - -// 1. Zalo¾ení listù/Podrozdìlení hran -\:if $\alpha = \varepsilon$: -\::if $\exists (v, a* )$ -\:::konec -\::else: -\:::zalo¾ím list -\:else if $\alpha \ne \varepsilon$: -\::if $\exists (v, \alpha a*)$: -\:::konec -\::else: -\:::podrozdìlím hranu na které le¾í $\alpha$ // za $\alpha$ vlo¾ím odboèku na $a$, kam dám list a pokraèuju - -// 2. Pøechod na dal¹í vrchol -\:zkrátim $\alpha$ zleva o znak -\:if $v = \varepsilon$: -\::pøejdu do $( \varepsilon, \alpha bez 1. znaku)$ -\:else: -\::pøejdu do $( back[v], \alpha )$ - -// 3. -\:kanonikalizuji // "jdu z $v$ pøes alpha do co nejdal" +\:Vstup: $\alpha=\alpha(\sigma)$ reprezentovaný jako kanonický referenèní pár $(\pi,\tau)$, $T$ suffixový strom pro~$\sigma$ a jeho funkce \, nový znak~$a$. +\:Zjistíme, jestli $\alpha a$ je pøitomen ve~stromu: +\::Pokud $\tau=\varepsilon$: ($\alpha=\pi$ je vnitøní vrchol) +\:::Vede-li z~vrcholu $\pi$ hrana s~nálepkou zaèínající znakem $a$, pak je pøítomen. +\:::Nevede-li, není pøítomen, a~tak pøidáme novou otevøenou hranu vedoucí do~nového listu. +\::Pokud $\tau\ne\varepsilon$: ($\alpha$ je skrytý vrchol) +\:::Najdeme hranu, po~ní¾ z~$\pi$ pokraèuje slovo $\tau$ (která to je, poznáme podle prvního znaku slova~$\tau$). +\:::Pokud v~popisce této hrany po~$\tau$ následuje znak~$a$, pak je $\alpha a$ pøítomen. +\:::Pokud nenásleduje, tak nebyl pøítomen, èili tuto hranu rozdìlíme: pøidáme na~ní nový vnitøní vrchol, + do~nìj¾ povede hrana s~popiskou~$\tau$ a z~nìj zbytek pùvodní hrany a otevøená hrana do~nového listu. +\:Pokud $\alpha a$ byl pøítomen, tak $\alpha$ zkrátíme a test opakujeme: +\::Je-li $\pi\ne\varepsilon$, nastavíme $\pi := \(\pi)$. V~opaèném pøípadì (jsme v~koøeni) zkrátíme $\tau$ o~znak zleva. +\::Pár $(\pi,\tau)$ u¾ popisuje zkrácené slovo, ale nemusí být kanonický, tak¾e to je¹tì napravíme: +\:::Dokud existuje hrana vedoucí z~$\pi$, její¾ popiska je prefixem slova $\tau$, tak se + po~této hranì posuneme, èili prodlou¾íme $\pi$ o~tuto popisku a zkrátíme o~ni~$\tau$. +\::Zpìt na~krok 2. +\:Pokud $\alpha a$ u¾ je pøítomen, zbývá pøidat $a$ k~$\alpha$ a zastavit se: +\::$\tau := \tau a$. +\::Kanonikalizace stejnì jako v~bodech 12--13. +\:Výstup: $\alpha=\alpha(\sigma a)$ coby kanonický referenèní pár $(\pi,\tau)$, $T$ suffixový strom pro~$\sigma a$ + a jeho funkce \. \endalgo - \s{Èasová slo¾itost:} -\numlist\ndotted -\:Zalo¾ení listu/Podrozdìlení hrany -- $O(1)$ -\:Pøechod na dal¹í vrchol -- $O(1)$ za pøedpokladu existence $back(v)$ -\:Kanonikalizace -- amortizovanì za $O(1)$ -\:Update $back[v]$ -- jen pro vnitøní vrcholy, které vznikly v 1. podrozdìlením hrany. Ta hrana vede do vrcholu, který nav¹tíví pøí¹tí update v kroku 2. a buï tam ten vrchol je, nebo ho v tom kroku zakláda, tedy -- $O(1)$. -\endlist + +Kanonikalizace pracuje v~amortizovanì konstantním èase, proto¾e ka¾dá její iterace +zkrátí~$\tau$ a za~celou dobu bìhu algoritmu se~$\tau$ prodlou¾í jen jednou, a~to o~jeden znak. + +Prùchodù hlavním cyklem je, jak u¾ víme, amortizovanì konstantní poèet a ka¾dý prùchod +zvládneme v~konstantním èase. + +Je¹tì jsme ale zapomnìli nastavovat novým vrcholùm jejich \. To potøebujeme +jen pro vnitøní vrcholy (na~zpìtné hrany z~listù se algoritmus nikdy neodkazuje) +a v¹imneme si, ¾e pokud jsme zalo¾ili vrchol, odpovídá tento vrchol v¾dy souèasnému~$\alpha$ +a zpìtná hrana z~nìj povede do~zkrácení slova~$\alpha$ o~znak zleva, co¾ je +pøesnì vrchol, který zalo¾íme (nebo zjistíme, ¾e u¾ existuje) v~pøí¹tí iteraci +hlavního cyklu. V~dal¹í iteraci urèitì je¹tì nebudeme tuto hranu potøebovat, +proto¾e $\pi$ v¾dy jen zkracujeme, a~tak mù¾eme vznik zpìtné hrany o~iteraci +zpozdit a zvládnout to tak také v~èase $\O(1)$. + +Celkovì je tedy èasová slo¾itost inkrementálního udr¾ování suffixového +stromu amortizovanì konstantní. +\qed \bye