Movatterモバイル変換


[0]ホーム

URL:


Zum Inhalt springen
WikipediaDie freie Enzyklopädie
Suche

Hirschberg-Algorithmus

aus Wikipedia, der freien Enzyklopädie

DerHirschberg-Algorithmus berechnet das paarweiseSequenzalignment und hat einen zur Eingabelinearen Speicherbedarf. Der in den 1970er Jahren vonDan Hirschberg entwickelteAlgorithmus verwendet die Methode derDynamischen Programmierung und dasDivide-and-conquer Prinzip.

Allgemeines

[Bearbeiten |Quelltext bearbeiten]

Der Hirschberg-Algorithmus ist ein allgemein einsetzbarer und optimaler Algorithmus zum Auffinden eines Sequenzalignment. Der bekannteBLAST-Algorithmus und derFASTA-Algorithmus sind nur suboptimale Heuristiken. Vergleicht man den Hirschberg-Algorithmus mit demNeedleman-Wunsch-Algorithmus, so handelt es sich beim Hirschberg-Algorithmus weniger um einen komplett neuen Algorithmus, sondern eher um eine clevere Strategie, die den Needleman-Wunsch-Algorithmus geschickt einsetzt, um den Speicherverbrauch zulinearisieren, was auch das Besondere an diesem Algorithmus ist: Die Berechnungen für ein Sequenzalignment benötigen nur linear viel Speicherplatz, womit diePlatzkomplexität des Algorithmus inO(n) liegt. Zur Berechnung eines Alignments zweier Zeichenkettenx{\displaystyle x} undy{\displaystyle y}mitm=|x|{\displaystyle m=|x|} undn=|y|{\displaystyle n=|y|} besitzt der Algorithmus eine LaufzeitvonΘ(mn){\displaystyle \Theta (mn)} und einen Speicherverbrauch vonΘ(min{m,n}){\displaystyle \Theta (\min\{m,n\})}. O.B.d.A soll im Folgendennm{\displaystyle n\leq m} gelten, so dass der Platzbedarf inΘ(n){\displaystyle \Theta (n)} liegt.

Anwendung findet der Algorithmus zum Beispiel in derBioinformatik zum Abgleich verschiedenerDNA- oderProteinsequenzen.

In einer leicht abgewandelten Form wird Hirschbergs Algorithmus auch dazu verwendet, um in einemGraphen parallelZusammenhangskomponenten mit AufwandΘ(log2n){\displaystyle \Theta (\log ^{2}n)} aufΘ(n2){\displaystyle \Theta (n^{2})} Prozessoren zu berechnen.

Berechnung der Levenshtein-Distanz auf linearem Speicherplatz

[Bearbeiten |Quelltext bearbeiten]

Zum Verständnis des Hirschberg-Algorithmus ist es zunächst wichtig zu verstehen, dass sich dieLevenshtein-Distanz auf linearem Speicherplatz berechnen lässt:

01T0{\displaystyle T_{0}} := 002 for j in 1..n loop03Tj{\displaystyle T_{j}} :=Tj1{\displaystyle T_{j-1}} +Ins(yj){\displaystyle Ins(y_{j})}04 end loop05 for i in 1..m loop06       s :=T0{\displaystyle T_{0}}07T0{\displaystyle T_{0}} :=T0{\displaystyle T_{0}} +Del(xi){\displaystyle Del(x_{i})}08       c :=T0{\displaystyle T_{0}}09       for j in 1..n loop10             c :=min{s+Sub(xi,yj)Tj+Del(xi)c+Ins(yj){\displaystyle \min {\begin{cases}s&+Sub(x_{i},y_{j})\\T_{j}&+Del(x_{i})\\c&+Ins(y_{j})\end{cases}}}11             s :=Tj{\displaystyle T_{j}}12Tj{\displaystyle T_{j}} := c13       end loop14 end loop

In den Zeilen 1–4 wird das eindimensionale FeldT{\displaystyle T} mit n Plätzen Speicherbedarf initialisiert. In Zeile 6 wird die Initialisierung des ersten ElementsT0{\displaystyle T_{0}} ins{\displaystyle s} gerettet.Danach wirdT0{\displaystyle T_{0}} undc{\displaystyle c} mit dem Startwert für die nächste Zeile initialisiert. Die nachfolgende Abbildung zeigt eine Momentaufnahme eines Zeilendurchlaufs.In der inneren Schleife zeigtc{\displaystyle c} immer auf das jeweils zuvor berechnete Ergebnis, währends{\displaystyle s} das noch benötigte Ergebnis der letzten Zeile sichert. Nach Zeile 14steht dieLevenshtein-Distanz als Ergebnis inTn{\displaystyle T_{n}}.

εy1{\displaystyle y_{1}}y2{\displaystyle y_{2}}y3{\displaystyle y_{3}}y4{\displaystyle y_{4}} ...ε0  1  2  3  ...x1{\displaystyle x_{1}}1x2{\displaystyle x_{2}}...
s =0c =T0{\displaystyle T_{0}} =1

Es sollte klar sein, dass sich diese Berechnung auch rückwärts durchführen lässt. Dabei wird die gedachte Matrix nicht von links nach rechts und von oben nach unten durchlaufen, sondern von rechts unten nach links oben:

01Tn{\displaystyle T_{n}} := 002 for j in n-1..0 loop03Tj{\displaystyle T_{j}} :=Tj+1{\displaystyle T_{j+1}} +Ins(yj+1){\displaystyle Ins(y_{j+1})}04 end loop05 for i in m-1..0 loop06       s :=Tn{\displaystyle T_{n}}07Tn{\displaystyle T_{n}} :=Tn{\displaystyle T_{n}} +Del(xi+1){\displaystyle Del(x_{i+1})}08       c :=Tn{\displaystyle T_{n}}09       for j in n-1..0 loop10             c :=min{s+Sub(xi+1,yj+1)Tj+Del(xi+1)c+Ins(yj+1){\displaystyle \min {\begin{cases}s&+Sub(x_{i+1},y_{j+1})\\T_{j}&+Del(x_{i+1})\\c&+Ins(y_{j+1})\end{cases}}}11             s :=Tj{\displaystyle T_{j}}12Tj{\displaystyle T_{j}} := c13       end loop14 end loop

Berechnung des Alignments auf linearem Speicherplatz

[Bearbeiten |Quelltext bearbeiten]

Der Divide-&-Conquer-Algorithmus vonHirschberg berechnet ein Alignment der Zeichenketten|x|{\displaystyle |x|} und|y|{\displaystyle |y|}, indem er Vorwärts- und Rückwärtsdurchlauf miteinander kombiniert (Zeilenangaben beziehen sich auf dennachfolgend angegebenen Pseudocode):

1. Wenn|x|=1{\displaystyle |x|=1} oder|y|=1{\displaystyle |y|=1} liegt eintriviales Alignment-Problem vor (Zeilen 14 – 22). Ein String bestehend aus nur einem Zeichen muss auf einen anderen String ausgerichtet werden und ein Alignment wird zurückgegeben. Ist|x|>1{\displaystyle |x|>1} und|y|>1{\displaystyle |y|>1} geht man über zu Schritt 2.

2. EinVorwärtsdurchlauf berechnet ein Alignment vony{\displaystyle y} und derersten Hälfte vonx{\displaystyle x} (Zeilen 27 – 40). Das Ergebnis des Vorwärtsdurchlaufs ist ein FeldT{\displaystyle T^{\ell }}, dessen Elemente die Kosten für einen Durchlauf von(0,0){\displaystyle (0,0)} bis(|x|/2,j){\displaystyle (|x|/2,j)} (mit0jn{\displaystyle 0\leq j\leq n}) angeben.

3. EinRückwärtsdurchlauf berechnet ein Alignment vony{\displaystyle y} mit derzweiten Hälfte vonx{\displaystyle x} (Zeilen 42 – 55). Das Ergebnis ist ein weiteres FeldTr{\displaystyle T^{r}}, dessen Elemente die Kosten für einen Durchlauf von(n,m){\displaystyle (n,m)} zurück zu(|x|/2,j){\displaystyle (|x|/2,j)} angeben.

4. In den FeldelementenT(n){\displaystyle T^{\ell }(n)} undTr(0){\displaystyle T^{r}(0)} stehen die beidenLevenshtein-Distanzen für die globalen Alignments vony{\displaystyle y} und den jeweiligen Hälften vonx{\displaystyle x}. In den restlichen Elementen vonT{\displaystyle T^{\ell }} stehen die Distanzen von der erstenx{\displaystyle x}-Hälfte zu allen Präfixen vony{\displaystyle y}. Entsprechend enthalten die restlichen Elemente vonTr{\displaystyle T^{r}} die Distanzen von der zweitenx{\displaystyle x}-Hälfte zu allen Suffixen vony{\displaystyle y}.

5. DieLevenshtein-Distanz vonx{\displaystyle x} zuy{\displaystyle y} kann nun errechnet werden, indem man entlang der mittleren Zeile der Alignment-Matrix läuft und nach einer kleinsten Summe von korrespondierendenT{\displaystyle T^{\ell }}- undTr{\displaystyle T^{r}}-Elementen sucht. Ist eine solche minimale Summe gefunden, hat man eine Position in der mittleren Zeile gefunden, in der das optimale Alignment die mittlere Zeile bzw. die Mitte vonx{\displaystyle x} schneidet. An dieser Stelle wirdy{\displaystyle y} in zwei Teile zerteilt und damit kann auch das Alignment-Problem in zwei kleinere Alignment-Probleme zerteilt werden (Zeilen 59 – 65).

6. Schritt 1 wird rekursiv auf den beiden Teilen vonx{\displaystyle x} undy{\displaystyle y} aufgerufen. Die beiden rekursiven Aufrufe geben Teil-Alignments zurück, die zu einem einzigen Alignment verknüpft werden. Das Alignment wird zurückgegeben (Zeilen 68 und 69).

01 --02 -- DerDivide-&-Conquer-Algorithmus von Hirschberg zur03 -- Berechnung des globalen Alignments auf linearem Speicher.04 --05 -- Beim=|x|,n=|y|,nm{\displaystyle m=|x|,n=|y|,n\leq m} besitzt der Algorithmus eine Laufzeit vonΘ(nm){\displaystyle \Theta (nm)}06 -- und einen Speicherverbrauch vonΘ(n){\displaystyle \Theta (n)}.07 --08 function HirschbergAlignment(x,y : string) return A is09        function SubAlignment(i1{\displaystyle i_{1}},j1{\displaystyle j_{1}},i2{\displaystyle i_{2}},j2{\displaystyle j_{2}} : integer) return A is10                mitte,cut : integer11                s,c : real12T,Tr{\displaystyle T^{\ell },T^{r}} : array(j1{\displaystyle j_{1}}..j2{\displaystyle j_{2}}) of real13        begin14                ifi1+1=i2{\displaystyle i_{1}+1=i_{2}} orj1=j2{\displaystyle j_{1}=j_{2}} then15                        -- Konstruiere Matrix T für die Teil-Strings16                        -- x(i1+1{\displaystyle i_{1}+1}..i2{\displaystyle i_{2}}) und y(j1+1{\displaystyle j_{1}+1}..j2{\displaystyle j_{2}})17                        -- Achtung: Nur linearer Speicherplatz erforderlich!18                        T := ...19                        -- Berechnetriviales Alignment auf Matrix T20                        -- in linearer Laufzeit21                        return Alignment(T,x(i1+1{\displaystyle i_{1}+1}..i2{\displaystyle i_{2}}),y(j1+1{\displaystyle j_{1}+1}..j2{\displaystyle j_{2}}))22                end if2324                mitte :=(i1+i2)/2{\displaystyle (i_{1}+i_{2})/2}25                -- finde ausgehendvon(i1,j1){\displaystyle (i_{1},j_{1})} den minimalen Pfad26                -- mit dem Vorwärtsalgorithmus:27T(j1){\displaystyle T^{\ell }(j_{1})} := 028                for j inj1+1{\displaystyle j_{1}+1}..j2{\displaystyle j_{2}} loop29T(j){\displaystyle T^{\ell }(j)} :=T(j1)+Ins(yj){\displaystyle T^{\ell }(j-1)+Ins(y_{j})}30                end loop31                for i ini1+1{\displaystyle i_{1}+1}..mitte loop32                        s :=T(j1){\displaystyle T^{\ell }(j_{1})}33                        c :=T(j1)+Del(xi){\displaystyle T^{\ell }(j_{1})+Del(x_{i})}34T(j1){\displaystyle T^{\ell }(j_{1})} := c35                        for j inj1+1{\displaystyle j_{1}+1}..j2{\displaystyle j_{2}} loop36                                c :=min{T(j)+Del(xi)s+Sub(xi,yj)c+Ins(yj){\displaystyle \min {\begin{cases}T^{\ell }(j)&+Del(x_{i})\\s&+Sub(x_{i},y_{j})\\c&+Ins(y_{j})\end{cases}}}37                                s :=T(j){\displaystyle T^{\ell }(j)}38T(j){\displaystyle T^{\ell }(j)} := c39                        end loop40                end loop41                -- finde minimalen score-pfadnach(i2,j2){\displaystyle (i_{2},j_{2})}42Tr(j2){\displaystyle T^{r}(j_{2})} := 043                for j inj21{\displaystyle j_{2}-1}..j1{\displaystyle j_{1}} loop44Tr(j){\displaystyle T^{r}(j)} :=Tr(j+1)+Ins(yj+1){\displaystyle T^{r}(j+1)+Ins(y_{j+1})}45                end loop46                for i ini21{\displaystyle i_{2}-1}..mitte loop47                        s :=Tr(j2){\displaystyle T^{r}(j_{2})}48                        c :=Tr(j2)+Del(xi+1){\displaystyle T^{r}(j_{2})+Del(x_{i+1})}49Tr(j2){\displaystyle T^{r}(j_{2})} := c;50                        for j inj21{\displaystyle j_{2}-1}..j1{\displaystyle j_{1}} loop51                                c :=min{Tr(j)+Del(xi+1)s+Sub(xi+1,yj+1)c+Ins(yj+1){\displaystyle \min {\begin{cases}T^{r}(j)&+Del(x_{i+1})\\s&+Sub(x_{i+1},y_{j+1})\\c&+Ins(y_{j+1})\end{cases}}}52                                s :=Tr(j){\displaystyle T^{r}(j)}53Tr(j){\displaystyle T^{r}(j)} := c54                        end loop55                end loop56                -- finde den Punkt ausj1{\displaystyle j_{1}}..j2{\displaystyle j_{2}} in dem der Minimale Pfad die57                -- mittlere Zeile schneidet:58                --cut:=defargminj1jj2(T(j)+Tr(j)){\displaystyle cut:=_{def}{\mbox{argmin}}_{j_{1}\leq j\leq j_{2}}(T^{\ell }(j)+T^{r}(j))}59                for j inj1{\displaystyle j_{1}}..j2{\displaystyle j_{2}} loop60                        if j=j1{\displaystyle j_{1}} then61                                cut :=j1{\displaystyle j_{1}}62                        elsifT(j)+Tr(j)<T(cut)+Tr(cut){\displaystyle T^{\ell }(j)+T^{r}(j)<T^{\ell }(cut)+T^{r}(cut)} then63                                cut := j64                        end if65                end loop66                -- Alignment entsteht durch Konkatenation von linkem und67                -- rechtem Teil-Alignment:68                return SubAlignment(i1{\displaystyle i_{1}},j1{\displaystyle j_{1}},mitte,cut)69{\displaystyle \star } SubAlignment(mitte,cut,i2{\displaystyle i_{2}},j2{\displaystyle j_{2}})70        end SubAlignment71        m,n : integer72 begin73        m :=|x|{\displaystyle |x|}; n :=|y|{\displaystyle |y|}74        -- Sonderbehandlung:x{\displaystyle x} ist der leere String und lässt keine Zerteilung zu:75        if m=0 then76                return(y1)(y2)(yn){\displaystyle {\begin{pmatrix}-\\y_{1}\end{pmatrix}}\star {\begin{pmatrix}-\\y_{2}\end{pmatrix}}\star \cdots \star {\begin{pmatrix}-\\y_{n}\end{pmatrix}}}77        else78                return SubAlignment(0,0,m,n)79        end if80 end HirschbergAlignment

Literatur

[Bearbeiten |Quelltext bearbeiten]
  • D. S. Hirschberg:A linear space algorithm for computing maximal common subsequences. In:Communications of the ACM.Band 18,Nr. 6, 1975,S. 341–343 (englisch,uci.edu [PDF]). 
  • Chao, K.M., Hardison, R.C. and Miller, W.:Recent developments in linear-space alignment methods: a survey. In:Journal of Computational Biology.Nr. 4, 1994,S. 271–291 (englisch,edu.tw [PDF]). 
Abgerufen von „https://de.wikipedia.org/w/index.php?title=Hirschberg-Algorithmus&oldid=248887649
Kategorien:

[8]ページ先頭

©2009-2026 Movatter.jp