From: Martin Mares Date: Fri, 8 Dec 2006 23:41:34 +0000 (+0100) Subject: Bitove triky. X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=f386e64dd8032aa74cbc707e7130bc7a9f0c6122;p=ga.git Bitove triky. --- diff --git a/7-ram/7-ram.tex b/7-ram/7-ram.tex index adbae2c..7828281 100644 --- a/7-ram/7-ram.tex +++ b/7-ram/7-ram.tex @@ -1,14 +1,12 @@ \input ../sgr.tex -\long\def\onecol#1{\hbox to 0.5\hsize{\vtop{\hsize=0.45\hsize #1}\hss}} -\long\def\twocol#1#2{\par\line{\onecol{#1}\hss\onecol{#2}}} -\def\austere{\parskip=0pt\parindent=0pt} -\def\lines{\obeylines\austere} -\def\\{\hfil\break} +% Makra pro bitove operace \def\rack#1#2{\setbox0=\hbox{#1}\hbox to \wd0{#2}} -% Alik -% ---- +\newdimen\slotwd +\def\slot#1{\hbox to \slotwd{\hfil #1\hfil}} +\def\[#1]{\slot{$#1$}} + \def\0{{\bf 0}} \def\1{{\bf 1}} \def\9{\rack{\0}{\hss$\cdot$\hss}} @@ -17,11 +15,10 @@ \def\shr{\mathop{>\!>}} \def\opdiv{\mathop{/}} \def\opmod{\mathop{\%}} -\def\ALIK{{\sc Alik}} \def\alik#1{% \medskip -\halign{\qquad $ ##$&\hbox to 0.4\hsize{${}##$\hfil}&\hfil $ ##$&\hbox to 0.4\hsize{${}##$ \hss}\cr +\halign{\hskip 0.3\hsize\hfil $ ##$&\hbox to 0.4\hsize{${}##$ \hss}\cr #1} \medskip } @@ -30,322 +27,368 @@ \h{Druhy výpoèetních modelù} -\s{Poznámka:} V dostateènì silném výpoèetním modelu lze v¹e (a¾ na -vyjímky) spoèítat v konstantním èase. - -\s{Church - Turingova teze:} V¹echny výpoèetní modely které nejsou -absurdní jsou ekvivalentní. - - Toto tvrzení ale neplatí a¾ do tìch nejmen¹ích detailù, které by nás zajímaly. Spoèítáme to samé, -ale pøi zkoumání jemnìj¹ích slo¾itostí ne¾ polynomiálních nejsou -modely stejnì silné. - -Následující modely se li¹í v tom, zda vìøíme, ¾e lze pole -indexovat v konstantním èase nebo ne. +Kdy¾ jsme v~pøede¹lých kapitolách studovali algoritmy, nezabývali jsme se tím, +v~jakém pøesnì výpoèetním modelu pracujeme. Konstrukce, které jsme pou¾ívali, +toti¾ fungovaly ve~v¹ech obvyklých modelech a mìly tam stejnou èasovou +i prostorovu slo¾itost. Ne~v¾dy tomu tak je, tak¾e se výpoèetním modelùm +podívejme na~zoubek trochu blí¾e. + +Obvykle se pou¾ívají následující dva modely, které se li¹í zejména v~tom, +zda je mo¾né pamì» indexovat v~konstantním èase èi nikoliv. + +\s{Pointer Machine (PM)} pracuje se dvìma typy dat: {\I èísly} v~pevnì omezeném +rozsahu a {\I pointery,} které slou¾í k~odkazování na~data ulo¾ená v~pamìti. +Pamì» tohoto modelu je slo¾ená z pevného poètu registrù na~èísla a +na~pointery a z~neomezeného poètu {\I krabièek.} Ka¾dá krabièka má pevný +poèet polo¾ek na èísla a pointery. Na~krabièku se lze odkázat pouze +pointerem. + +Aritmetika v~tomto modelu (a¾ na triviální pøípady) nefunguje v~konstantním +èase, datové struktury popsatelné pomocí pointerù (seznamy, stromy \dots) fungují +pøímoèaøe, ov¹em pole musíme reprezentovat stromem, tak¾e indexování stojí +$\O(\log n)$. + +\s{Random Access Machine (RAM)} je rodinka modelù, které mají spoleèné to, ¾e +pracují výhradnì s~(pøirozenými) èísly a ukládají je do~pamìti indexované +opìt èísly. Instrukce v~programu (podobné assembleru) pracují s~operandy, +které jsou buï konstanty nebo buòky pamìti adresované pøímo (èíslem buòky), +pøípadnì nepøímo (index je ulo¾en v~nìjaké buòce adresované pøímo). +Je~vidìt, ¾e tento model je alespoò tak silný jako PM, proto¾e odkazy +pomocí pointerù lze v¾dy nahradit indexováním. + +Pokud ov¹em povolíme poèítat s~libovolnì velkými èísly v~konstantním èase, +dostaneme velice silný paralelní poèítaè, na~nìm¾ spoèítáme témìø v¹e +v~konstantním èase (modulo kódování vstupu). Proto musíme model nìjak +omezit, aby byl realistický, a~to lze udìlat více zpùsoby: -\s{Pointer Machine:} Uznává 2 typy dat: +\itemize\ibull +\:{\I Zavést logaritmickou cenu instrukcí} -- operace trvá tak dlouho, +kolik je poèet bitù èísel, s~nimi¾ pracuje, a~to vèetnì adres v~pamìti. +Elegantnì odstraní absurdity, ale je dost tì¾ké odhadovat èasové slo¾itosti; +u~vìt¹iny normálních algoritmù nakonec po~dlouhém poèítání vyjde, ¾e mají +slo¾itost $\O(\log n)$-krát vìt¹í ne¾ v~neomezeném RAMu. + +\:{\I Omezit velikost èísel} na~$w$ bitù a operace ponechat v~èase $\O(1)$. +Jeliko¾ potøebujeme umìt alespoò adresovat vstup, je $w=\Omega(\log n)$.% +\foot{Pøesnìji, plyne z~toho jen, ¾e $w\ge\log_2 n$, ale to je ekvivalentní, +proto¾e aritmetiku s~$\O(1)$-násobnou pøesností mù¾eme simulovat +s~konstantním zpomalením. S~$\O(\log n)$ bity se ov¹em pracuje daleko +pøíjemnìji, proto¾e si mù¾eme v¾dy dovolit ukládat èísla polynomiálnì +velká vzhledem k~$n$.} Je¹tì bychom si mìli ujasnit, jakou mno¾inu +operací povolíme: -\algo -\: Èísla - jsou omezená parametry modelu -\: Pointry - -ukazují na "krabièky" -\endalgo +\itemize\ibull +\:{\I Word-RAM} -- \uv{céèkové} operace: $+$, $-$, $*$, $/$, $\bmod$ (aritmetika); +$\shl$, $\shr$ (bitové posuvy); $\land$, $\lor$, $\oplus$, $\opnot$ (bitový and, or, xor a negace). + +\:{\I $AC^0$-RAM} -- libovolné funkce spoèítatelné hradlovou sítí polynomiální +velikosti a konstantní hloubky s~hradly o~libovolné mnoho vstupech.\foot{Pro zvídavé: +$AC^k$ je tøída v¹ech funkcí spoèítetelných polynomiálnì velkou hradlovou +sítí hloubky $\O(\log^k n)$ s~libovolnìvstupovými hradly a $NC^k$ toté¾ +s~omezením na~hradla se dvìma vstupy. V¹imnìte si, ¾e $NC^0\subseteq AC^0 \subseteq NC^1 \subseteq AC^1 \subseteq NC^2 \subseteq \ldots$.} +To je teoreticky èist¹í, patøí sem v¹e z~pøedchozí skupiny mimo násobení, +dìlení a modula, a~také spousta dal¹ích operací. + +\:{\I Kombinace pøedchozího} -- tj. pouze operace Word-RAMu, které jsou v~$AC^0$. +\endlist -Pamì» tohoto modelu je slo¾ená z pevného poètu registrù na èísla a -na pointry a neomezeného poètu krabièek. Ka¾dá krabièka má pevný -poèet polo¾ek na èísla a pointry a na krabièku se lze odkázat -pointrem. Aritmetika není a¾ na triviální pøípady v konstantním -èase. +\endlist -\s{Random Access Machine:} Je rodinka modelù, které se li¹í v -rùzných detailech. Ov¹em dost podstatných. V¹echny mají spoleèné -to, ¾e existuje pouze jeden datový typ - {\bf èísla}, mají pevný -poèet registrù (do jednoho registru se vejde jedno èíslo) a pamì», -co¾ je pole indexované èísly, jeho¾ polo¾ky jsou èísla. Instrukce -jsou operace s èísly. +V~zbytku této kapitoly uká¾eme, ¾e na~RAMu lze poèítat mnohé vìci +efektivnìji ne¾ na~PM. Zamìøíme se pøevá¾nì na~Word-RAM, podobné konstrukce +jdou provést i na~$AC^0$-RAMu. (Kombinace obou omezení vede ke~slab¹ímu modelu.) -Tento model má dvì nejasnosti: +\h{Van Emde-Boas Trees} -\algo -\: Velikost èísel -\: Cena operací -\endalgo +VEBT jsou RAMová struktura, která si pamatuje mno¾inu prvkù $X$ z nìjakého +omezeného universa $X \subseteq \{0,\ldots,U-1\}$, a umí s~ní provádìt +\uv{stromové operace} (vkládání, mazání, nalezení následníka apod.) v~èase +$\O(\log\log U)$. Pomocí takové struktury pak napøíklad doká¾eme: -\h {Typy Random Access Machine (RAM)} +$$\vbox{\halign{ +#\hfil\quad &#\hfil\quad &#\hfil\cr + & pomocí VEBT &nejlep¹í známé pro celá èísla \cr +\noalign{\smallskip\hrule\smallskip} +tøídìní &$\O(n\log\log U)$ &$\O(n\log\log n)$ \cr +MST &$\O(m\log\log U)$ &$\O(m)$ \cr +Dijkstra &$\O(m\log\log U)$ &$\O(m+n\log\log n)$, neorientovanì $\O(m)$\cr +}}$$ -\s{1) Logaritmická cena instrukcí} +\s{Definice:} VEBT($U$) pro universum velikosti $U$ (BÚNO $U=2^{2^k}$) +obsahuje: -Èasová slo¾itost instrukce roste s poètem bitù èísel, na kterých -instrukce pracuje. Dojde tím k odstranìní absurdit, ale ¹patnì se -poèítá $\O(x)$. +\itemize\ibull -\s{2) Omezení velikosti slova; Operace v $\O(1)$} +\:\, \ reprezentované mno¾iny (mohou být i nedefinovaná, pokud je mno¾ina moc malá) -$W$ - ¹íøka slova. Mám li vstup délky $n$, pak $W$ je alespoò -$\log n$. Mù¾eme BÚNO pøedpokládat, ¾e $W = \O(\log n)$. Není to -zcela ekvivalentní prvnímu RAM, ale dovedeme na nìj pøevést se -zpomalením $\O(\log n)$. Máme k dispozici nìkolik modelù operací: +\:{\I pøihrádky} $P_0, \ldots, P_{\sqrt{U}}$ obsahující zbývající +hodnoty.\foot{Alespoò jedno z~\, \ musí být ulo¾eno zvlá¹», +aby strom obsahující pouze jednu hodnotu nemìl ¾ádné podstromy. +My jsme pro eleganci struktury zvolili zvlá¹» obojí.} +Hodnota $x$ padne do~$P_{\lfloor x/\sqrt{U} \rfloor}$. +Ka¾dá pøíhrádka je ulo¾ena jako VEBT($\sqrt{U}$), který obsahuje pøíslu¹ná èísla $\bmod \sqrt{U}$. +[Bity ka¾dého èísla jsme tedy rozdìlili na~vy¹¹ích $k/2$, které indexují +pøíhrádku, a~ni¾¹ích $k/2$ uvnitø pøíhrádky.] -\algo -\:WordRAM - +, -, *, /, \%, <<, >>, \&,\^{} +\:Navíc je¹tì {\I \uv{sumární}} VEBT($\sqrt{U}$) obsahující èísla neprázdných pøihrádek. +\endlist -\:AC$^0$ RAM - Jsou funkce spoèitatelné hradlovou sítí, která má -polynomiální poèet hradel, libovolný poèet vstupù a konstantní -hloubku. +\s{Operace} se~strukturou budeme provádìt následovnì: -\:AC$^k$ - Jsou funkce spoèitatelné hradlovou sítí, která má -polynomiální poèet hradel, libovolný poèet vstupù a hloubku $ -\O(\log^k n)$. +\>\ -- minimum nalezneme v~koøeni v~èase $\O(1)$. -\:MC$^k$ - Jsou funkce spoèitatelné hradlovou sítí, která má -polynomiální poèet hradel a má nejvý¹e 2 vrstvy. +\>$\(x)$ -- pøímoèaøe rekurzí pøes pøíhrádky v~èase $\O(k)$. -\: Word $\cap$ AC$^0$ - Mù¾eme v¹e, kromì *, /, \%. Nejedná se ale -o pøíli¹ zajímavý model . +\>$\(x)$: +\algo +\:O¹etøíme triviální stromy (prázdný a jednoprvkový) +\:Je-li tøeba, prohodíme $x$ s \, \ +\:Prvek $x$ padne do pøihrádky $P_i$, která je buï: +\::prázdná $\Rightarrow$ Insert~$i$ do~sumárního stromu a zalo¾ení +triviálního stromu pro pøihrádku; nebo +\::neprázdná $\Rightarrow$ pøevedu na~Insert v~podstromu. \endalgo -Zamìøíme se pøevá¾nì na WordRAM, ale ve¹keré operace lze vyrobit i -v AC$^0$RAM. - -\s{Poznámka:} Ve¹keré Pointer-Machine polynomiání algoritmy, jsem -schopen na RAM spoèíst v asymptoticky stejném èase. - -\h {Van Emde-Boas Trees} - -Struktura, která si pamatuje mno¾inu uzlù $X$ z nìjakého omezeného -universa $U$, $X \subseteq \{0..U-1\}$ a podporují "stromové -operace" v èase $\O(\log\log U)$. Stromovými operacemi jsou -my¹leny základní mno¾inové operace a operace pracující s -uspoøádáním. V takovéto struktuøe pak mají operace slo¾itost: - -\settabs 5 \columns \+ & VEBT & Best Known\cr \+ Tøídìní & -$\O(n\log\log U)$ & $\O(n\log\log n)$ \cr \+ MST & $\O(m\log\log -U)$ & $\O(m)$ - pro integerovì ohodnocené\cr \+ Dijkstra & -$\O(m\log\log U)$ & $\O(m+n\log\log U)$, neorientovanì $\O(m)$\cr +V~ka¾dém pøípadì buï rovnou skonèíme nebo pøevedeme na~Insert v~jednom stromu +ni¾¹ího øádu a k~tomu vykonáme konstantní práci. Celkem tedy $\O(k)$. - -VEBT pro universum velikosti $U$ (WLOG $U=2^{2^K}$) obsahuje: +\>$\(x)$: (slo¾itost opìt $\O(k)$) \algo - -\:min, max - alespoò jedno nesmí být ulo¾eno rekurzivnì v -podstromech - -\:pøihrádky $P_0$ -- $P_{\sqrt{U}}$, pøièem¾ $x$ padne do -$P_{\lfloor x/\sqrt{U} \rfloor}$ a pøihrádky jsou ulo¾ené jako -VEBT($\sqrt{U}$) - -\:"sumární" VEBT($\sqrt{U}$) obsahující èísla neprázdných -pøihrádek +\:O¹etøíme triviální stromy (jednoprvkový a dvouprvkový) +\:Pokud ma¾eme \ (analogicky \), nahradíme ho minimem +z~první neprázdné pøíhrádky (tu najdeme podle sumárního stromu) +a pøevedeme na~Delete v~této pøíhrádce. +\:Prvek~$x$ padne do~pøíhrádky $P_i$, která je buï: +\::jednoprvková $\Rightarrow$ zru¹ení pøíhrádky a Delete ze~sumárního stromu; nebo +\::vìt¹í $\Rightarrow$ Delete ve~stromu pøíhrádky. \endalgo -\s{Find:} - pøímoèaøe v $\O(\log\log U)$ +\>$\(x)$: (nalezne nejmen¹í prvek vìt¹í ne¾~$x$, opìt v~èase $\O(k)$) -\s{Insert:} Slo¾itost $\O(\log\log U)$ \algo - -\:o¹etøení triviálních stromù - -\: je-li tøeba, swap s min/max - -\: padne do pøihrádky $P_i$, která je buï - -\:: prázdná $\Rightarrow$ update sumárního stromu + zalo¾ení -triviálního stromu pro pøihrádku - -\:: nìco v ní je $\Rightarrow$ zanoøím do podstromu +\:Triviální pøípady: pokud $x<\$, vrátíme \; pokud $x\ge\$, +vrátíme, ¾e následník neexistuje. +\:Prvek~$x$ padne do~pøíhrádky $P_i$ a buïto: +\::$P_i$ je prázdná nebo $x=\(P_i)$ $\Rightarrow$ pomocí Succ +v~sumárním stromu najdeme nejbli¾¹í dal¹í neprázdnou pøíhrádku $P_j$: +\:::existuje-li $\Rightarrow$ vrátíme $\(P_j)$, +\:::neexistuje-li $\Rightarrow$ vrátíme \. +\::nebo $x<\(P_i)$ $\Rightarrow$ pøevedeme na~Succ v~$P_i$. \endalgo -\s{Delete:} - analogicky +Slo¾itosti operací jsou pìkné, ale nesmíme zapomenout, ¾e strukturu +je na~poèátku nutné inicializovat, co¾ trvá $\Omega(\sqrt U)$. +Z~následujících úvah ov¹em vyplyne, ¾e si inicializaci mù¾eme +odpustit. -\s{FindMin:} - Slo¾itost $\O(1)$ +\h{Modely inicializace} -\s{Succ:} - Slo¾itost $\O(\log\log U)$ -\algo +\>Jak mù¾e definován obsah pamìti na~poèátku výpoètu: -\: porovnání $x$ s min a max +\s{\uv{Pøi odchodu zhasni}:} Zavedeme, ¾e pamì» RAMu je na~poèátku +inicializována nulami a program ji po~sobì musí uklidit (to je nutné, +aby programy ¹lo iterovat). To u~VEBT není problém zaøídit. -\:: $x$ = min $\Rightarrow$ i=FindMin(sumarni strom); Succ = -FindMin($P_i$) \:: $x$ = max $\Rightarrow$ Succ = 0 +\s{Neinicializovano:} Na~¾ádné konkrétní hodnoty se nemù¾eme spolehnout, +ale je definováno, ¾e neinicializovanou buòku mù¾eme pøeèíst a dostaneme +nìjakou korektní, i kdy¾ libovolnou, hodnotu. Tehdy nám pomù¾e: -\: $x \in P_i$ +{\narrower -\:: $x \not =$ max $P_i$ $\Rightarrow$ vnoøím do $P_i$ +\s{Vìta:} Buï $P$ program pro Word-RAM s~nulami inicializovanou +pamìtí bì¾ící v èase $T(n)$. Pak existuje program~$P'$ pro Word-RAM +s~neinicializovanou pamìtí poèítající toté¾ v~èase~$\O(T(n))$. -\:: $x =$ max $P_i$ $\Rightarrow$ j=Succ(i) v sumárním stromu; -Succ = FindMin($P_j$) -\endalgo +\s{Dùkaz:} Bìhem výpoètu si budeme pamatovat, ve~kterých pamì»ových +buòkách u¾ nìco máme. Prokládanì ulo¾íme do pamìti dvì pole: +$M$, co¾ bude pamì» pùvodního stroje, a~$L$ -- seznam èísel bunìk +v~$M$, do~kterých u¾ program zapsal. Pøitom $L[0]$ bude udávat +délku seznamu~$L$. -Na operace mám hezké slo¾itosti, ale s inicializací to tak pìkné -není. Nicménì z následujícího vyplyne, ¾e není tøeba inicializaci -psát. +Program nyní zaène tím, ¾e vynuluje $L[0]$ a bude simulovat pùvodní +program, pøièem¾ kdykoliv ten bude chtít pøeèíst nìjakou buòku +z~$M$, podíváme se do~$L$, zda u¾ je inicializovaná, a~pøípadnì +vrátíme nulu a buòku pøipí¹eme do~$L$. -\h{Modely inicializace} +To je funkèní, ale pomalé. Redukci tedy vylep¹íme tak, ¾e zalo¾íme dal¹í +prolo¾ené pole~$R$, jeho¾ hodnota $R[i]$ bude øíkat, kde v~$L$ se vyskytuje +èíslo $i$-té buòky, nebo bude neinicializována, pokud +takové místo neexistuje. -\s{1) "Pøi odchodu zhasni":} Pøidáme axióm, ¾e na zaèátku je celá -pamì» vynulovaná. Za sebou pak pamì» uklidíme. +Pøed ètením $M[i]$ se tedy podíváme na~$R[i]$ a ovìøíme, zda $R[i]$ nele¾í +mimo seznam~$L$ a zda je $L[R[i]]=i$. Tím v~konstantním èase ovìøíme, +jestli je $M[i]$ ji¾ inicializovaná, a~jsme také schopni tuto informaci +v~tém¾e èase udr¾ovat. +\qed +} -\s{2) Neinicializovano:} V pamìti je cokoliv, musím se postarat -sám +\s{\uv{Minové pole}:} Neinicializované buòky není ani dovoleno èíst. +V~tomto pøípadì nejsme schopni deterministické redukce, ale alespoò +mu¾eme pou¾ít randomizovanou -- ukládat si obsah pamìti do~hashovací +tabulky, co¾ pøí pou¾ití universálního hashování dá~slo¾itost $\O(1)$ +na~operaci v~prùmìrném pøípadì. -\s{Vìta:} Buï $P$ program pro WordRAM s nulami inicializované -pamìti bì¾ící v èase $T(n)$. Pak existuje program $P$' pro WordRAM -s {\bf neinicializovanou} pamìtí poèítající toté¾ v -èase$\O(T(n))$. +\h{Technické triky} -\s{Dùkaz:} Bìhem výpoètu si budeme pamatovat, k terých pamì»ových -buòkách u¾ nìco máme. Prokládaòe ulo¾íme do pamìti 2 pole: -\itemize\ibull \:M - pamì» $P$ \:L - seznam pou¾itých bunìk v M a -L[0] = délka L -\endlist +VEBT nedosahují zdaleka nejlep¹ích mo¾ných parametrù -- lze sestrojit +i struktury pracující v~konstantním èase. To v~následující kapitole také +udìláme, ale nejdøíve v~této ponìkud technické stati vybudujeme repertoár +základních operací proveditelných na~Word-RAMu v~konstantním èase. -Redukci vylep¹íme tím, ¾e zalo¾íme dal¹í prolo¾ené pole R, ve -kterém $i$-tá polo¾ka je buï neinicializovaná nebo øíká, na které -pozici v L je $i$-tá pamì»ová buòka pùvodního stroje.R[$i$] = $j$: -L[$j$] = $i$ $\vee$ neinicializováno pokud $\not \exists$ takové $j$. +\>Rozcvièka: {\I nejpravìj¹í jednièka} ve~dvojkovém èísle (hodnota, nikoliv pozice): +\alik{ + x&=\0\1\9\9\9\0\1\1\0\0\9\9\9\0 \cr + x - 1&=\0\1\9\9\9\0\1\0\1\1\9\9\9\1 \cr + x \land (x - 1)&=\0\1\9\9\9\0\1\0\0\0\9\9\9\0 \cr + x \oplus (x \land (x - 1))&=\0\0\9\9\9\0\0\1\0\0\9\9\9\0 \cr} -Tak¾e jsem schopen v konstantním èase rozhodnout, -jestli u¾ do buòky bylo psáno a ve stejném èase teké buòku pøidat. +\>Nyní uká¾eme, jak RAM pou¾ívat jako vektorový poèítaè, který umí paralelnì +poèítat se v¹emi prvky vektoru, pokud se dají zakódovat do~jediného slova. +Libovolný $n$-slo¾kový vektor, jeho¾ slo¾ky jsou $b$-bitová èísla +($n(b+1)\le w$), zakódujeme poskládáním jednotlivých slo¾ek vektoru za~sebe, +prolo¾enì nulovými bity: +\alik{\0 x_{n-1} \0 x_{n-2} \9\9\9 \0 x_1\0 x_0 \cr} -\qed +\>S~vektory budeme provádìt následující operace: -\s{3) Zákaz dìr:} $\Rightarrow$ randomizované +\itemize\ibull -\s{Dùsledek:}Ani v jednom z pøedchozích pøípadù nemusíme psát -inicializaci +\:$\(\alpha)$ -- vytvoøí vektor $(\alpha,\alpha,\ldots,\alpha)$: + \alik{\alpha*(\0^b\1)^n \cr} -\h{Operace s RAM} +\:$\(x)$ -- seète v¹echny slo¾ky vektoru (pøedpokládáme, ¾e se vejdou do~$b$~bitù): -Dá se s jistými omezeními pou¾ívat jako vektorový poèítaè. - \itemize\ibull +\numlist\nalpha +\:sèítáním modulo $\1^{n+1}$ (uvìdomte si, ¾e $\1\0^{n+1}\bmod \1^{n+1}=1$) +\:násobením vhodnou konstantou: +\setbox0=\hbox{~$x_{n-1}$} +\slotwd=\wd0 +\def\.{\[]} +\def\z{\[\0^b\1]} +\def\dd{\slot{$\cdots$}} +\def\vd{\slot{$\vdots$}} +\def\rule{\noalign{\medskip\nointerlineskip} +$\hrulefill$\cr +\noalign{\nointerlineskip\medskip}} -\:Nejpravìj¹í jednièka: \alik{ - & & x&=\0\1\9\9\9\0\1\1\0\0\9\9\9\0 \cr - & & x - 1&=\0\1\9\9\9\0\1\0\1\1\9\9\9\1 \cr - & & x \land (x - 1)&=\0\1\9\9\9\0\1\0\0\0\9\9\9\0 \cr - & & x \oplus (x \land (x - 1))&=\0\0\9\9\9\0\0\1\0\0\9\9\9\0 \cr} +\[x_{n-1}] \dd \[x_2] \[x_1] \[x_0] \cr +*~~ \z \dd \z\z\z \cr +\rule +\[x_{n-1}] \dd \[x_2] \[x_1] \[x_0] \cr +\[x_{n-1}] \[x_{n-2}] \dd \[x_1] \[x_0] \. \cr +\[x_{n-1}] \[x_{n-2}] \[x_{n-3}] \dd \[x_0] \. \. \cr +\vd\vd\vd\vd\.\.\.\cr +\[x_{n-1}] \dd \[x_2]\[x_1]\[x_0] \. \. \. \. \cr +\rule +\[r_{n-1}] \dd \[r_2] \[r_1] \[s_n] \dd \[s_3] \[s_2] \[s_1] \cr +} +Zde je výsledkem je dokonce vektor v¹ech èásteèných souètù: +$s_k=\sum_{i=0}^{k-1}x_i$, $r_k=\sum_{i=k}^{n-1}x_i$. \endlist -Pro následující sadu vektorových operací vezmeme vektor, a -prolo¾íme jeho jednotlivé prvky zleva nulami. \itemize\ibull - - \alik{ & & \0 x_{n-1} \0 x_{n-2} \9\9\9 \0 x_1\0 x_0 \cr} - -\: Replikace: - -Replikace $x$ vytvoøí vektor samých $x$ - \alik{ & & x*(\0\0\9\9\9\0\0\1)^n \cr} +\:$\(x,y)$ -- paralelní porovnání dvou vektorù: $i$-tá slo¾ka výsledku je~1, pokud +$x_i(\alpha,x)$ -- spoèítá, kolik slo¾ek vektoru~$x$ je men¹ích ne¾~$\alpha$: -\alik{ & & x_{n-1} x_{n-2} \9\9\9\9 x_1 x_0 \cr - & & * \y\y \9\9\9\9 \z\z \cr - & & x_{n-1} x_{n-2} \9\9\9\9 x_1 x_0 \cr - & & x_{n-1} x_{n-2} \xb\9\9 x_1 x_0 \xa \cr - & & \| \xa\xa\xa\xa\xa\xa\xa \cr - & & \| \xa\xa\xa\xa\xa\xa\xa \cr - & & \9\9\9 x_1x_0\xa\xa\xa\xa\xa\xa\xa \cr - } -Výsledkem je vektor v¹ech èásteèných souètù. +\alik{\(\alpha,x) = \(\(\(\alpha),x))\cr} -\: Paralelní porovnání $(Cmp)$: +\:$\(\alpha,x)$ -- zatøídí hodnotu $\alpha$ do~setøídìného vektoru~$x$: -Compare x $\leq$ y $\equiv z_i = 1 \Leftrightarrow x_i \leq y_i$ -\alik{ & & \1 y_{n-1} \1 y_{n-2} \9\9\9 \1 y_1\1 y_0 \cr & & - \0 -x_{n-1} \0 x_{n-2} \9\9\9 \0 x_1\0 x_0 \cr \cr} +Zde staèí pomocí operace \ zjistit, na~jaké místo novou hodnotu +zatøídit, a~pak to pomocí bitových operací provést (\uv{roz¹oupnout} +existující hodnoty). -U vektoru y nahradíme prolo¾ené nuly jednièkami a odeèteme vektor -x. Ve výsledku pak bude na místì prolo¾eného bitu jednièka právì -tehdy, kdy¾ $x_i \leq y_i$ +\:$\(\alpha)$ -- vytvoøí vektor, jeho¾ slo¾ky jsou bity zadaného èísla +(jinými slovy prolo¾í bity $b$~nulami). -\: Rank ($x$,y): +Nejdøíve èíslo~$\alpha$ replikuje, pak anduje vhodnou bitovou maskou, +aby v~$i$-té slo¾ce zùstal pouze $i$-tý bit a ostatní se vynulovaly, +a pak provede $\$ s~vektorem samých nul. -Mám nìjaké èíslo $x$ a vektor y, Rank je poèet slo¾ek vektoru, -které jsou men¹í nebo rovny $x$. \alik{ & & -Sum(Cmp((xx\9\9\9xx),y)) \cr} +\:$\_\varphi(\alpha)$ -- podobnì jako pøedchozí operace, ale bity je¹tì +prohází podle nìjaké pevné funkce $\varphi$: -Nareplikuji vektor samých $x$ a ten porovnám s vektorem y. -Výsledný vektor seètu. +Staèí zvolit bitovou masku, která na~$i$-té pozici ponechá právì $\varphi(i)$-tý bit. -\: Zatøídìní: +\:$\(x)$ -- dostane vektor nul a jednièek a vytvoøí èíslo, jeho¾ bity +jsou právì slo¾ky vektoru (jinými slovy ¹krtne nuly mezi bity): -Zatøídit novou hodnotu do setøídìného vektoru èísel lze také v -konstantním èase. Nejprve pomocí Rank najdu místo, kam má pøijít, -pak nìjakým konstantním poètem operací vektor "roz¹oupnu" o ¹íøku -slo¾ky doleva a vlo¾ím novou hodnotu. +Pøedstavím si, ¾e slo¾ky èísla jsou o~jeden bit krat¹í a provedu \. +Napøíklad pro $n=4$ a $b=4$: -\: Unpack: +\setbox0=\hbox{$x_3$} +\slotwd=\wd0 +\def\z{\[\0]} -Dostane $k$-bitové èíslo a vyrobí $k$-slo¾kový vektor, jeho¾ -slo¾ky jsou bity pùvodního èísla. Zreplikuji $x$ na vektor \alik{ -& & \0x\0x\9\9\9\0x \cr} a provedu AND s vhodnou bitovou maskou, -konkrétnì \alik{ & & -\1\0\9\9\9\0\|\9\9\9\|\0\9\9\9\0\1\0\|\0\9\9\9\0\1 \cr} Tím -vytvoøím vektor, který má v ka¾dé slo¾ce nulu nebo nenulu, podle -toho, jestli bit odpovídající této slo¾ce je nulový nebo nenulový, -ale je na ¹patné pozici. Vektor teï prolo¾ím jednièkami místo nul -a odeètu jednièku v ka¾dé slo¾ce. Tam kde byla ve slo¾ce nula, tak -si vypùjèila z jednièky od prostrkání, kde byla nenula tam se -nevypùjèilo. Prokládací bity jsou teï negace tìch, které tam -potøebuji mít. Pak staèí znegovat, provést Shift na správné místo -a AND k odstranìní nepoøádku. +\def\|{\hskip1pt\vrule height 10pt depth 4pt\hskip1pt} +\def\.{\hphantom{\|}} -\: Pack: +\alik{ +\|\z\.\z\.\z\.\z\.\[x_3]\|\z\.\z\.\z\.\z\.\[x_2]\|\z\.\z\.\z\.\z\[x_1]\|\z\.\z\.\z\.\z\.\[x_0]\|\cr +\|\z\.\z\.\z\.\z\|\[x_3]\.\z\.\z\.\z\|\z\.\[x_2]\.\z\.\z\|\z\.\z\[x_1]\.\z\|\z\.\z\.\z\.\[x_0]\|\cr +} -Dìlá opak ne¾ unpack, dostane vektor jednièek a nul, ze kterého -vytvoøí $k$-bitové èíslo. Pøerozdìlím slo¾ky vektoru tak, jako by -byli o bit krat¹í a provedu $Sum$ - Tím se jednotlivé bity posunou -a posèítá se to, jak potøebuju. +Jen si musíme dát pozor na~to, ¾e vytvoøený vektor s~krat¹ími slo¾kami +není korektnì prostrkán nulami. Konstrukce \ pomocí modula proto +nebude správnì fungovat a místo $\1^b$ vygeneruje $\0^b$, co¾ mù¾eme +buïto o¹etøit zvlá¹», nebo pou¾ít konstrukci pøes násobení, které +to nevadí. \endlist -Pro dal¹í operace pøedpokládáme, ¾e pro $W$-bitová èísla máme -slova dlouhá alespoò $b^2$. +\>Nyní je¹tì nìkolik operací s~normálními èísly. Zatím pøedpokládejme, +¾e pro~$b$-bitová èísla na~vstupu budeme mít k~dispozici $b^2$-bitový +pracovní prostor. \itemize\ibull -\: Poèet jednièek: - -Zjistí poèet jednièkových bitù. Provedu Unpack, èím¾ dostanu -vektor, jeho¾ slo¾ky jsou bity pùvodního èísla a provedu $Sum$. +\:$\#1(\alpha)$ -- spoèítá jednièkové bity v~zadaném èísle. -\: Zrcadlení: +Staèí provést \ (výsledek se dokonce vejde do~$b\log b$ bitù) +a následnì \. -Chci dostat zrcadlovì symetrické èíslo ke vstupnímu. Nejprve -provedu Replicate. V nejni¾¹í kopii si nechám nejvýznamìj¹í bit, v -dal¹í druhý, a¾ v poslední nejni¾¹í bit. Poté posèítám s o jedna -men¹í velikostí bloku. +\:$\_\pi(\alpha)$ -- pøehází bity podle zadané fixní permutace. -\: LSB (Least Significant Bit): +Provedeme $\_\pi$ a \ zpìt. -Poøadové èíslo první jednièky zprava. Izoluji tento bit pomocí -nalezení nejpravìj¹í jednièky, \alik{& & \0\9\9\9\0\1\0\9\9\9\0 -\cr} odeètu 1 a seètu jednièky. \alik{& & \0\9\9\9\0\0\1\9\9\9\1 -\cr} +\:$\(\alpha)$ -- Least Significant Bit (pozice nejni¾¹í jednièky): -\: MSB (Most Significant Bit): +Podobnì jako v~rozcvièce nejdøíve vytvoøíme èíslo, které obsahuje +nejni¾¹í jednièku a vpravo od~ní dal¹í jednièky, a~pak tyto jednièky +posèítáme pomocí $\#1$: -Provede se pøes zrcadlení. +\alik{ +\alpha&= \9\9\9\9\9\1\0\0\0\0\cr +\alpha-1&= \9\9\9\9\9\0\1\1\1\1\cr +\alpha\oplus(\alpha-1)&= \0\9\9\9\0\1\1\1\1\1\cr +} -\: MSB pro normální délu slova: +\:$\(\alpha)$ -- Most Significant Bit (nejpravìj¹í): -Rozdìlím èíslo na bloky velikosti $\lfloor\sqrt{w}\rfloor$, -nejdøíve v ka¾dém bloku zjistím, zda v nìm nìco je nebo ne - -$Cmp(x,0)$, provedu Pack, èím¾ dostanu jedno slovo $y$ odmocninové -délky, které øíká, které bloky jsou prázdné a které ne. Dále -pustím MSB kvadratické na $y$, èím¾ dostanu blok $B_i$, ve kterém -je nejpravìj¹í jednièka a nakonec pustím MSB kvadratické na blok -$B_i$. Tím ji najdu uvnitø bloku. +Z~\ pomocí zrcadlení. \endlist + +\>Poslední dvì operace doká¾eme spoèítat i v~lineárním prostoru, napøíklad +pro \ takto: Rozdìlíme èíslo na bloky velikosti $\lfloor\sqrt{w}\rfloor$. +Pak pro ka¾dý blok zjistíme, zda v nìm je aspoò jedna jednièka, zavoláním +$\(0,x)$. Pomocí \ z~toho dostaneme slovo~$y$ odmocninové +délky, jeho¾ bity indikují neprázdné bloky. Na~toto èíslo zavoláme pøedchozí +kvadratické \, èím¾ zjistíme index nejvy¹¹ího neprázdného bloku. +Ten pak izolujeme a druhým voláním kvadratického algoritmu najdeme nejlevìj¹í +jednièku uvnitø nìj. + \bye diff --git a/sgr.tex b/sgr.tex index 9759e48..fa4de4a 100644 --- a/sgr.tex +++ b/sgr.tex @@ -65,7 +65,7 @@ \def\algohang:{\advance\hangindent by 2em \hskip 2em\futurelet\next\algoitemh} % Nekolikapismenkova promenna (mozno pouzit v textovem i math modu) -\def\<#1>{\hbox{\it #1}} +\def\<#1>{\hbox{\it #1\/}} % Asymptoticke O-cko \def\O{{\cal O}}