WSPÓLNE PODCIĄGI
7. Najdłuższy wspólny podciąg
7.3. Algorytmy sekwencyjne i równoległości bitowej
7.3.5. Algorytm równoległości bitowej – wariant Hirschberga
Algorytm LCS-BP-Sequence do wyznaczenia podciągu LCS wymaga Θ(ndm/we) słów pamięci. Możliwe jest jednak zastosowanie do niego metody Hirschberga w celu zmniejsze-nia złożoności pamięciowej bez zmiany złożoności czasowej. Modyfikacja ta jest stosunkowo prosta [51]. Pewnej uwagi wymagają jednak dwie kwestie, tj. obsługa małych podmacierzy (ta-kich, których wysokość jest nie większa niż w) oraz problem znalezienia wiersza dzielącego macierz na dwie mniejsze podmacierze, które to problemy niestety nie zostały przedyskutowa-ne w [51].
Ogólna idea jest jednak taka sama jak w oryginalnym algorytmie Hirschberga. Macierz dzie-lona jest na dwie części i każda z nich jest obliczana algorytmem BP niezależnie, z tym że w
czę-3Prezentowany tu algorytm wyznaczania podciągu LCS odnosi się do omawianego algorytmu Hyyrö. W [121]
pokazano algorytm wyznaczania podciągu LCS oparty na algorytmie równoległości bitowej Crochemore’a i in. [52].
LCS-BP-Sequence(A, B, V , `)
Wejście: A, B – ciągi, dla których wyznaczany jest podciąg LCS
V – tablica wektorów bitowych V wyznaczanych algorytmem LCS-BP-Length
` – długość podciągu LCS (wynik działania algorytmu LCS-BP-Length(A, B)) Wyjście: znaleziony podciąg LCS
1 `∗← `; i ← n; j← m
Rys. 7.8. Algorytm równoległości bitowej wyznaczania podciągu LCS z macierzy wygenerowanej algo-rytmem LCS-BP-Length
Fig. 7.8. Bit-parallel algorithm recovering an LCS from the matrix produced by LCS-BP-Length algo-rithm
Rys. 7.9. Przykład działania algorytmu równoległości bitowej wyznaczania podciągu LCS. Ciągiem wy-nikowym jest BAADCBA. Lewa część: macierz programowania dynamicznego (tylko dla po-równania). Prawa część: przejście po macierzy bitowej. Dla prostoty prezentacji bity w słowach numerowane są od 1
Fig. 7.9. An example of the bit-parallel algorithm by Hyyrö for the LCS problem. The output sequence is BAADCBA. Left: DP matrix just for comparison of what is going on. Right: backtracking on bit matrix. Note that for simplicity of presentation the bits in Hyyrö’s algorithm are numbered from 1
ści prawej ciągi są odwrócone (oczywiście wymaga to, aby istniały dwie tablice wektorów ma-sek: dla ciągu B i odwróconego ciągu B). Następnie dla każdej części macierzy algorytm wyko-nywany jest rekurencyjnie, aż dojdzie do sytuacji, w której wysokość podmacierzy nie przekra-cza w. Dla takiej podmacierzy wykonuje się zwykły algorytm równoległości bitowej, w którym przechowuje się całą podmacierz reprezentowaną na wektorach bitowych. Z uwagi na niewielką wysokość tej podmacierzy, każdy wektor bitowy mieści się w pojedynczym słowie komputero-wym, a całkowita zajętość pamięciowa tej bitowej podmacierzy to liczba słów równa jej szero-kości. Małe podmacierze pojawiają się w końcowym etapie rekurencji i nie mogą obejmować
7.3. Algorytmy sekwencyjne i równoległości bitowej 103 tych samych kolumn, a więc sumaryczna złożoność pamięciowa dla nich wszystkich jest O(n) słów, a obliczane są w czasie O(n). Ponieważ na każdym poziomie rekurencji szerokość ma-cierzy zmniejsza się o połowę, więc maksymalna liczba poziomów rekurencji wynosi dlog2ne.
Pozostaje teraz do oszacowania liczba operacji na słowach komputerowych na kolejnych po-ziomach rekurencji. Na każdym poziomie macierz dzielona jest na podmacierze o rozłącznych zakresach wierszy i kolumn. Niech wysokości wszystkich podmacierzy, które są większe niż w, wynoszą m1, m2, . . . , mkdla pewnego k < dm/we, a szerokości tych podmacierzy na j-tym po-ziomie rekurencji wynoszą nie więcej niż dn/2je. Liczba operacji na słowach komputerowych na tym poziomie rekurencji dla takich podmacierzy wynosi wtedy:
∑
k i=1lmi
w ml n
2j
m=l n 2j
m k
i=1
∑
lmi
w
m≤l n 2j
m 2lm
w
m. (7.8)
Sumując po wszystkich poziomach rekurencji, otrzymuje się O
nlm w
m. (7.9)
Wynik ten nie uwzględnia jednak problemu wyznaczenia indeksów wierszy dzielących macie-rze. W tym celu należy przeglądnąć wektory bitowe sąsiednich kolumn, zliczając liczbę bitów o wartości0. Ponieważ na każdym z dlog2ne poziomów rekurencji sumaryczna długość wszyst-kich wektorów bitowych znajdujących się na granicach podziału podmacierzy jest O(m) bitów, więc sumarycznie czas potrzebny na te operacje w całym algorytmie jest
O(m log n), (7.10)
a więc całkowita złożoność czasowa tego algorytmu to suma (7.9) i (7.10):
O
nlm
w m
+ m log n
. (7.11)
Jeśli m = O(w), to złożoność pamięciowa zwykłego algorytmu równoległości bitowej, w któ-rym przechowywane są wszystkie wektory bitowe kolumn, jestΘ(n) słów, a więc stosowanie wariantu Hirschberga nie ma sensu. Jeśli n = O(wlogw), to złożoność pamięciowa zwykłego algorytmu równoległości bitowej jest O(wlogwdwlogw/we) = O(wlog2w) słów, co w prakty-ce jest wielkością tak małą, że również wariant Hirschberga nie powinien być stosowany. Niech zatem m =ω(w) oraz n =ω(w log w), wtedy log n = O(n/w) i złożoność czasową (7.11) można wyrazić jako
Θ nlm
w m
, (7.12)
a więc tak samo jak w przypadku zwykłego algorytmu równoległości bitowej, podczas gdy złożoność pamięciowa jestΘ(n) słów. Na rys. 7.10 zilustrowano działanie tego algorytmu dla przypadku, gdy w = 2.
1
Rys. 7.10. Przykład działania algorytmu wyznaczania podciągu LCS opartego na metodzie równole-głości bitowej z wykorzystaniem metody Hirschberga o liniowej złożoności pamięciowej dla ciągów: ABAADACBAABC, CBCBDAADCDBA dla w = 2. Na kolejnych rysunkach przed-stawiono poziomy rekurencji. Kolumny zaznaczone na szaro pokazują przebieg podziału każ-dej (pod)macierzy. Pod macierzami wskazano, które symbole na danym poziomie rekurencji są wyznaczane. Wynik ostateczny to BAADCBA
Fig. 7.10. An example of the bit-parallel LCS computing algorithm with Hirschberg linear-space method computing the LCS for the sequences: ABAADACBAABC, CBCBDAADCDBA for w = 2. Fi-gures show recurrence levels. Greyed columns show (sub)matrix divisions. Below two bottom matrices the computed symbols are given. They form the result: BAADCBA
Algorytmy równoległości bitowej zarówno dla problemu LCS, jak i dla innych problemów wykorzystują pewne techniki bitowe, które są często mało oczywiste bez gruntownego zro-zumienia specyfiki reprezentacji liczb całkowitych i rzeczywistych w komputerach. Doskona-łe wprowadzenie do dziedziny operacji bitowych stanowią książki Warrena [215] oraz Knu-tha [131]. Interesująca może też być książka Korena [132].