<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://wiki-de.moshellshocker.dns64.de/index.php?action=history&amp;feed=atom&amp;title=Gotoh-Algorithmus</id>
	<title>Gotoh-Algorithmus - Versionsgeschichte</title>
	<link rel="self" type="application/atom+xml" href="https://wiki-de.moshellshocker.dns64.de/index.php?action=history&amp;feed=atom&amp;title=Gotoh-Algorithmus"/>
	<link rel="alternate" type="text/html" href="https://wiki-de.moshellshocker.dns64.de/index.php?title=Gotoh-Algorithmus&amp;action=history"/>
	<updated>2026-05-27T13:38:27Z</updated>
	<subtitle>Versionsgeschichte dieser Seite in Wikipedia (Deutsch) – Lokale Kopie</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://wiki-de.moshellshocker.dns64.de/index.php?title=Gotoh-Algorithmus&amp;diff=878318&amp;oldid=prev</id>
		<title>imported&gt;SchlurcherBot: Bot: http → https</title>
		<link rel="alternate" type="text/html" href="https://wiki-de.moshellshocker.dns64.de/index.php?title=Gotoh-Algorithmus&amp;diff=878318&amp;oldid=prev"/>
		<updated>2025-12-28T00:41:53Z</updated>

		<summary type="html">&lt;p&gt;Bot: http → https&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Der &amp;#039;&amp;#039;&amp;#039;Gotoh-Algorithmus&amp;#039;&amp;#039;&amp;#039; berechnet das [[Sequenzalignment|Alignment]] von zwei Sequenzen bei affinen Gapkosten. Er verwendet das Programmierparadigma der [[Dynamische Programmierung|dynamischen Programmierung]].&lt;br /&gt;
&lt;br /&gt;
== Affine Gapkosten ==&lt;br /&gt;
Mit affinen Gapkosten bezeichnet man Kosten für [[Gap (Bioinformatik)|Gaps]] in Alignments, welche sich durch eine [[lineare Funktion]] &amp;lt;math&amp;gt;g(l) = \text{gap}\_\text{start} + (l - 1) \times \text{gap}\_\text{extend}&amp;lt;/math&amp;gt; beschreiben lassen. Dabei ist &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt; die Länge des Gaps. &amp;lt;math&amp;gt;\text{gap}\_\text{start}&amp;lt;/math&amp;gt; sind die Kosten für den Start eines neuen Gap, und &amp;lt;math&amp;gt;\text{gap}\_\text{extend}&amp;lt;/math&amp;gt; sind die Kosten für die Erweiterung eines existierenden Gaps um eine Stelle&amp;lt;ref&amp;gt;[[Stephen F. Altschul &amp;amp; Bruce W. Erickson]]: &amp;#039;&amp;#039;Optimal sequence alignment using affine gap costs&amp;#039;&amp;#039; Bulletin of Mathematical Biology volume 48, 603–616 (1986), Springer, 1986&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Biologisch können affine Gapkosten mehr Sinn als rein lineare Gapkosten ergeben, da man eine Insertion bzw. Deletion von mehreren Zeichen in bestimmten Zusammenhängen als wahrscheinlicher betrachten möchte als eine Insertion oder Deletion von einem einzigen Zeichen, z.&amp;amp;nbsp;B. beim Alignieren von [[cDNA]] gegen Genom-[[DNA]] (Gusfield, 1999).&lt;br /&gt;
&lt;br /&gt;
== Matrix-Rekurrenzen ==&lt;br /&gt;
Spezifikation des Algorithmus durch [[Matrix (Mathematik)|Matrix]]-Rekurrenzen:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Initialisierung:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
A[0, 0] = 0&lt;br /&gt;
&lt;br /&gt;
B[0, 0] = 0&lt;br /&gt;
&lt;br /&gt;
C[0, 0] = 0&lt;br /&gt;
&lt;br /&gt;
A[i, 0] = C[i, 0] = -inf, 1 &amp;lt;= i &amp;lt;= m&lt;br /&gt;
&lt;br /&gt;
A[0, j] = B[0, j] = -inf, 1 &amp;lt;= j &amp;lt;= n&lt;br /&gt;
&lt;br /&gt;
B[i, 0] = g(i), 1 &amp;lt;= i &amp;lt;= m&lt;br /&gt;
&lt;br /&gt;
C[0, j] = g(j), 1 &amp;lt;= i &amp;lt;= n&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Rekursion:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A(i,j) = \max \begin{Bmatrix}&lt;br /&gt;
A(i-1, j-1) + w(u[i - 1], v[j - 1]) \\&lt;br /&gt;
B(i-1, j-1) + w(u[i - 1], v[j - 1]) \\&lt;br /&gt;
C(i-1, j-1) + w(u[i - 1], v[j - 1]  \\&lt;br /&gt;
\end{Bmatrix},\; 1\le i\le m,\; 1\le j\le n&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;B(i,j) = \max \begin{Bmatrix}&lt;br /&gt;
A(i - 1, j)+\text{gap}\_\text{start} \\&lt;br /&gt;
B(i - 1, j)+\text{gap}\_\text{extend} \\&lt;br /&gt;
C(i - 1, j)+\text{gap}\_\text{start}\\&lt;br /&gt;
\end{Bmatrix},\; 1\le i\le m,\; 1\le j\le n&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C(i,j) = \max \begin{Bmatrix}&lt;br /&gt;
A(i, j - 1)+\text{gap}\_\text{start} \\&lt;br /&gt;
B(i, j - 1)+\text{gap}\_\text{start} \\&lt;br /&gt;
C(i, j - 1)+\text{gap}\_\text{extend} \\&lt;br /&gt;
\end{Bmatrix},\; 1\le i\le m,\; 1\le j\le n&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* u,v – Sequenzen über einem Alphabet &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
* m = Länge(u), n = Länge(v)&lt;br /&gt;
* w(a, b),&amp;lt;math&amp;gt;a, b\in\Sigma&amp;lt;/math&amp;gt; - Ähnlichkeits-Funktion&lt;br /&gt;
* gap_start – Kosten für den Beginn eines Gaps&lt;br /&gt;
* gap_extend – Kosten für die Erweiterung eines Gaps&lt;br /&gt;
* g(l) - affine Gap-Kosten Funktion &amp;lt;math&amp;gt;g(l) = \text{gap}\_\text{start} + (l - 1)\times\text{gap}\_\text{extend}&amp;lt;/math&amp;gt;&lt;br /&gt;
* -inf = &amp;lt;math&amp;gt;-\infty&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
* A(i,j) – der optimale Similarity Score des optimalen Alignment des Präfixes u[1..i] von u und des Präfixes v[1..j] von v unter affinen Gapkosten&lt;br /&gt;
* B(i,j) – der optimale Similarity Score des optimalen Alignment des Präfixes u[1..i] von u und des Präfixes v[1..j] von v, welches mit einem Gap in u endet&lt;br /&gt;
* C(i,j) – der optimale Similarity Score des optimalen Alignment des Präfixes u[1..i] von u und des Präfixes v[1..j] von v, welches mit einem Gap in v endet&lt;br /&gt;
Der optimale Score des Alignments ist das Maximum von: A[m, n], B[m, n], C[m, n].&lt;br /&gt;
&lt;br /&gt;
Implementation in Pseudo-Code:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
//Initialisierung der Matrizen&lt;br /&gt;
a[0, 0] = 0;&lt;br /&gt;
b[0, 0] = 0;&lt;br /&gt;
c[0, 0] = 0;&lt;br /&gt;
&lt;br /&gt;
FOR i = 1; TO i &amp;lt;= m; i++;&lt;br /&gt;
    a[i, 0] = c[i, 0] = -inf;&lt;br /&gt;
    b[i, 0] = g(i);&lt;br /&gt;
&lt;br /&gt;
FOR j = 1; TO j &amp;lt;= n; j++;&lt;br /&gt;
    a[0, j] = b[0, j] = -inf;&lt;br /&gt;
    c[0, j] = g(j);&lt;br /&gt;
&lt;br /&gt;
//Berechnen der restlichen Matrix&lt;br /&gt;
FOR i = 1; TO i &amp;lt;= m; i++;&lt;br /&gt;
    FOR j = 1; TO j &amp;lt;= n; j++;&lt;br /&gt;
        a[i, j] = get_max(a[i - 1, j - 1],&lt;br /&gt;
                            b[i - 1, j - 1],&lt;br /&gt;
                            c[i - 1, j - 1]) +&lt;br /&gt;
                            match_or_mismatch(u[i - 1], v[j - 1]);&lt;br /&gt;
        b[i, j] = get_max(a[i - 1, j] + gap_start,&lt;br /&gt;
                            b[i - 1, j] + gap_extend,&lt;br /&gt;
                            c[i - 1, j] + gap_start);&lt;br /&gt;
        c[i, j] = get_max(a[i, j - 1] + gap_start,&lt;br /&gt;
                            b[i, j - 1] + gap_start,&lt;br /&gt;
                            c[i, j - 1] + gap_extend);&lt;br /&gt;
//Speichere Ergebnis&lt;br /&gt;
result = get_max(a[m, n], b[m, n], c[m, n]);&lt;br /&gt;
&lt;br /&gt;
function g(l)&lt;br /&gt;
    return gap_start + (l - 1) * gap_extend;&lt;br /&gt;
&lt;br /&gt;
function match_or_mismatch(x, y)&lt;br /&gt;
        if( x == y)&lt;br /&gt;
            return match_score;&lt;br /&gt;
        else&lt;br /&gt;
            return mismatch_score;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Implementation in C# (ohne Fehlerbehandlung):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
using System;&lt;br /&gt;
using System.IO;&lt;br /&gt;
using System.Linq;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
namespace DnaAlignment&lt;br /&gt;
{&lt;br /&gt;
    class Program&lt;br /&gt;
    {&lt;br /&gt;
        const int GAP_PENALTY_START = -10;&lt;br /&gt;
        const int GAP_PENALTY_EXTEND = -0.5;&lt;br /&gt;
        const int MIN_INF = int.MinValue + 100; //Pseudo-Unendlich&lt;br /&gt;
        const int MATCH = 3;&lt;br /&gt;
        const int MISMATCH = -3;&lt;br /&gt;
        static void Main(string[] args)&lt;br /&gt;
        {&lt;br /&gt;
            using (StreamReader reader = File.OpenText(args[0]))&lt;br /&gt;
                while (!reader.EndOfStream)&lt;br /&gt;
                {&lt;br /&gt;
                    string line = reader.ReadLine();&lt;br /&gt;
                    if (null == line)&lt;br /&gt;
                        continue;&lt;br /&gt;
                    string[] sSplit = line.Split(&amp;#039;|&amp;#039;);&lt;br /&gt;
                    if (sSplit.Count() != 2)&lt;br /&gt;
                        continue;&lt;br /&gt;
                    string seqA = sSplit[0].Trim(&amp;#039; &amp;#039;);&lt;br /&gt;
                    string seqB = sSplit[1].Trim(&amp;#039; &amp;#039;);&lt;br /&gt;
&lt;br /&gt;
                    //Initsialisiere Matrizen&lt;br /&gt;
                    int[,] a = new int[seqA.Length + 1, seqB.Length + 1];&lt;br /&gt;
                    int[,] b = new int[seqA.Length + 1, seqB.Length + 1];&lt;br /&gt;
                    int[,] c = new int[seqA.Length + 1, seqB.Length + 1];&lt;br /&gt;
                    a[0, 0] = 0;&lt;br /&gt;
                    b[0, 0] = 0;&lt;br /&gt;
                    c[0, 0] = 0;&lt;br /&gt;
                    for (int i = 1; i &amp;lt;= seqA.Length; i++)&lt;br /&gt;
                    {&lt;br /&gt;
                        a[i, 0] = c[i, 0] = MIN_INF;&lt;br /&gt;
                        b[i, 0] = G(i);&lt;br /&gt;
                    }&lt;br /&gt;
                    for (int j = 1; j &amp;lt;= seqB.Length; j++)&lt;br /&gt;
                    {&lt;br /&gt;
                        a[0, j] = b[0, j] = MIN_INF;&lt;br /&gt;
                        c[0, j] = G(j);&lt;br /&gt;
                    }&lt;br /&gt;
                    //Berechne Matrizen&lt;br /&gt;
                    for (int i = 1; i &amp;lt;= seqA.Length; i++)&lt;br /&gt;
                    {&lt;br /&gt;
                        for (int j = 1; j &amp;lt;= seqB.Length; j++)&lt;br /&gt;
                        {&lt;br /&gt;
                            a[i, j] = Get_Max_Value(&lt;br /&gt;
                                        a[i - 1, j - 1],&lt;br /&gt;
                                        b[i - 1, j - 1],&lt;br /&gt;
                                        c[i - 1, j - 1]) +&lt;br /&gt;
                                        Match_Or_Mismatch(seqA[i - 1], seqB[j - 1]);&lt;br /&gt;
                            b[i, j] = Get_Max_Value(&lt;br /&gt;
                                        a[i - 1, j] + GAP_PENALTY_START,&lt;br /&gt;
                                        b[i - 1, j] + GAP_PENALTY_EXTEND,&lt;br /&gt;
                                        c[i - 1, j] + GAP_PENALTY_START);&lt;br /&gt;
                            c[i, j] = Get_Max_Value(&lt;br /&gt;
                                        a[i, j - 1] + GAP_PENALTY_START,&lt;br /&gt;
                                        b[i, j - 1] + GAP_PENALTY_START,&lt;br /&gt;
                                        c[i, j - 1] + GAP_PENALTY_EXTEND);&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                    Console.WriteLine(Get_Max_Value(a[seqA.Length, seqB.Length],&lt;br /&gt;
                                        b[seqA.Length, seqB.Length],&lt;br /&gt;
                                        c[seqA.Length, seqB.Length]));&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
        private static int G(int index)&lt;br /&gt;
        {&lt;br /&gt;
            return GAP_PENALTY_START + (index - 1) * GAP_PENALTY_EXTEND;&lt;br /&gt;
        }&lt;br /&gt;
        private static int Get_Max_Value(int a, int b, int c)&lt;br /&gt;
        {&lt;br /&gt;
            return Math.Max(Math.Max(a, b), c);&lt;br /&gt;
        }&lt;br /&gt;
        private static int Match_Or_Mismatch(char a, char b)&lt;br /&gt;
        {&lt;br /&gt;
            return a == b ? MATCH : MISMATCH;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Effizienz ==&lt;br /&gt;
Die Laufzeit und der Speicherplatzbedarf des Algorithmus liegen in [[Landau-Symbole|O]](nm). Dies ist eine Verbesserung zum [[Needleman-Wunsch-Algorithmus]], welcher für beliebige Gapkosten eine Laufzeit von &amp;lt;math&amp;gt;O(nm^2+n^2m)&amp;lt;/math&amp;gt; hat.&lt;br /&gt;
Im schlimmsten Fall ist die Matrix quadratisch (&amp;lt;math&amp;gt;n=m&amp;lt;/math&amp;gt;), was beim Needleman-Wunsch-Algorithmus zu einer kubischen Laufzeit von &amp;lt;math&amp;gt;O(n^3 )&amp;lt;/math&amp;gt; führt. Durch den Gotoh-Algorithmus mit seinen linearen Gap-Kosten verringert sich die Komplexität auf &amp;lt;math&amp;gt;O(n^2 )&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Wenn nur der Score des optimalen Alignments berechnet werden soll, können alle Matrizen auch spalten- bzw. zeilenweise berechnet werden, da jeder Eintrag nur von der vorherigen Spalte bzw. Zeile abhängt. Also sinkt der Speicherplatzbedarf auf &amp;lt;math&amp;gt;O(m+n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Der Gotoh-Algorithmus kann auch mit der [[Teile und herrsche (Informatik)|Divide-and-Conquer]]-Methode implementiert werden, so dass das optimale Alignment mit linearem Platzbedarf berechnet werden kann. Siehe [[Hirschberg-Algorithmus]].&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
* {{Literatur&lt;br /&gt;
   |Autor=O. Gotoh&lt;br /&gt;
   |Titel=An improved algorithm for matching biological sequences&lt;br /&gt;
   |Sammelwerk=[[Journal of Molecular Biology]]&lt;br /&gt;
   |Band=162&lt;br /&gt;
   |Datum=1982&lt;br /&gt;
   |Seiten=705–708&lt;br /&gt;
   |Online=[https://jaligner.sourceforge.net/references/gotoh1982.pdf jaligner.sourceforge.net]&lt;br /&gt;
   |Format=PDF&lt;br /&gt;
   |KBytes=206}}&lt;br /&gt;
* {{Literatur&lt;br /&gt;
   |Autor=Eugene W. Myers und Webb Miller&lt;br /&gt;
   |Titel=Optimal alignments in linear space&lt;br /&gt;
   |Sammelwerk=Bioinformatics&lt;br /&gt;
   |Band=4&lt;br /&gt;
   |Nummer=1&lt;br /&gt;
   |Datum=1988&lt;br /&gt;
   |Seiten=11–17&lt;br /&gt;
   |Kommentar=Anwendung der linearen Speicherplatz Technik des [[Hirschberg-Algorithmus]] auf den Gotoh-Algorithmus&lt;br /&gt;
   |Online=[http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.123.327&amp;amp;amp;rep=rep1&amp;amp;amp;type=pdf citeseerx.ist.psu.edu]&lt;br /&gt;
   |Format=PDF&lt;br /&gt;
   |KBytes=&lt;br /&gt;
   |DOI=10.1093/bioinformatics/4.1.11}}&lt;br /&gt;
* J. Stoye: [https://www.techfak.uni-bielefeld.de/~stoye/dropbox/preprint102.pdf Divide-and-Conquer Multiple Sequence Alignment] (PDF; 938&amp;amp;nbsp;kB). Dissertation Thesis. Universität Bielefeld, Forschungsbericht der Technischen Fakultät, Abteilung Informationstechnik, Report 97-02, S. 26–27, 1997. {{ISSN|0946-7831}}&lt;br /&gt;
* D. Gusfield: &amp;#039;&amp;#039;Algorithms on Strings, Trees and Sequences.&amp;#039;&amp;#039; 11.8, 1999, ISBN 0-521-58519-8, S. 235–244.&lt;br /&gt;
* Saad Mneimneh: &amp;#039;&amp;#039;Computational Biology Lecture.&amp;#039;&amp;#039; 6: &amp;#039;&amp;#039;Affine gap penalty function, multiple sequence alignment.&amp;#039;&amp;#039;&amp;lt;ref&amp;gt;{{Internetquelle |url=https://www.cs.hunter.cuny.edu/~saad/courses/compbio/lectures/lecture6.pdf |titel=Affine gap penalty function, multiple sequence alignment |autor=Saad Mneimneh |hrsg= |werk= |datum= |sprache=en |zugriff=2015-08-15 |format=PDF}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://bibiserv.techfak.uni-bielefeld.de/cgi-bin/adp_AffineGlobSim bibiserv.techfak.uni-bielefeld.de] [[Common Gateway Interface|CGI]]-[[Skriptsprache|Script]] zur Berechnung von globalen Alignments mit affinen Gapkosten an der Universität Bielefeld&lt;br /&gt;
&lt;br /&gt;
== Einzelnachweise ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Bioinformatik]]&lt;br /&gt;
[[Kategorie:Optimierungsalgorithmus]]&lt;br /&gt;
[[Kategorie:Dynamische Programmierung]]&lt;/div&gt;</summary>
		<author><name>imported&gt;SchlurcherBot</name></author>
	</entry>
</feed>