From e64a1d711a2aee507cbad818c3aa06d240c82534 Mon Sep 17 00:00:00 2001 From: Samuel Ortion Date: Mon, 25 Mar 2024 12:04:13 +0100 Subject: [PATCH] Add variation on Needleman - Wunsch algorithm --- content/chapters/include.tex | 4 +- content/chapters/part1/4.bak0 | 116 ++++++++++++++++++++ content/chapters/part1/4.tex | 201 +++++++++++++++++----------------- content/chapters/part2/1.tex | 107 +++++++++++++++--- main.pdf | 4 +- tmp.pdf | 4 +- tmp.tex | 39 ++++++- 7 files changed, 356 insertions(+), 119 deletions(-) create mode 100644 content/chapters/part1/4.bak0 diff --git a/content/chapters/include.tex b/content/chapters/include.tex index d247ea5..e77d82d 100755 --- a/content/chapters/include.tex +++ b/content/chapters/include.tex @@ -11,7 +11,7 @@ } } -\includechapters{part1}{3} -\includechapters{part2}{2} +\includechapters{part1}{4} +\includechapters{part2}{4} % \includechapters{part3}{1} diff --git a/content/chapters/part1/4.bak0 b/content/chapters/part1/4.bak0 new file mode 100644 index 0000000..bf53b9c --- /dev/null +++ b/content/chapters/part1/4.bak0 @@ -0,0 +1,116 @@ +\chapter{Longest common subsequence} + +Let $S_{1} = \text{ATCTGAT}$ and $S_{2} = \text{TGCATA}$. +In this case the longest common subsequence of $S_{1}$ and $S_{2}$ is $TCTA$. +\begin{algorithm} + \caption{Construct a longest common subsequence matrix} + \begin{algorithmic}[1] + \Function{LCSQ\_Matrix}{$S_{1}$: Array($n$), $S_{2}$: Array($m$)} + \State $M \gets $ Array($m+1$, $n+1$) + \For{($i = 0$; $i < n+1$; $i++$)} + \For{$j = 0$; $j < m+1$; $j++$} + \If {$i = 0$ or $j = 0$} + \State $M[i][j] = 0$ + \Else + \If {$S_{1}[i] = S_{2}[j]$} + \State $match = M[i-1][j-1] + 1$ + \Else + \State $match = M[i-1][j-1]$ + \EndIf + \State $gap_{1} = M[i-1][j]$ + \State $gap_{2} = M[i][j-1]$ + \State $M[i][j] = \max \{ match, gap_{1}, gap_{2}\}$ + \EndIf + \EndFor + \EndFor + \State \Return $M$ + \EndFunction + \end{algorithmic} + \end{algorithm} + +\begin{algorithm} + \caption{Construct a longest common subsequence matrix keeping the path in memory} + \begin{algorithmic}[1] + \Function{LCSQ\_Matrix\_Path}{$S_{1}$: Array($n$), $S_{2}$: Array($m$)} + \State $M \gets $ Array($m+1$, $n+1$) + \State $P \gets $ Array($m+1$, $n+1$) + \For {($i = 0$; $i < n+1$, $i++$)} + \State $M[i][0] \gets 0$ + \EndFor + \For {($j = 0$; $j < m+1$; $j+$)} + \State $M[0][j] \gets 0$ + \EndFor + \For{($i = 1$; $i < n+1$; $i++$)} + \For{($j = 1$; $j < m+1$; $j++$)} + \If {$i = 1$ or $j = 0$} + \State $M[i][j] = 0$ + \Else + \If {$S_{1}[i-1] = S_{2}[j-1]$} + \State $M[i][j] \gets M[i-1][j-1] + 1$ + \State $P[i][j] \gets '\nwarrow'$ + \ElsIf {$M[i][j-1] \geq M[i-1][j]$} + \State $M[i][j] \gets M[i][j-1]$ + \State $P[i][j] \gets '\leftarrow'$ + \Else + \State $M[i][j] \gets M[i-1][j]$ + \State $P[i][j] \gets '\downarrow'$ + \EndIf + \EndFor + \EndFor + \State \Return $M, P$ + \EndFunction + \end{algorithmic} + \end{algorithm} + +\begin{algorithm} + \caption{Backtrack the longest common subsequence} + \begin{algorithmic}[1] + \Function{LCSQ}{$S_{1}$: Array($n$), $S_{2}$: Array($m$)} + \State $M, P \gets $ \Call{LCSQ\_Matrix}{$S_{1}$, $S_{2}$} + \State $L \gets Array(M[n][m])$ + \State $k \gets 0$ + \State $i \gets n$ + \State $j \gets m$ + \While{$i > 0$ and $j > 0$} + \If {$P[i][j] = '\nwarrow' $} + \State $L[k] \gets S_{1}[i]$ + \State $i--$ + \State $j--$ + \State $k++$ + \ElsIf {$P[i][j] = '\leftarrow'$} + \State $j--$ + \Else + \State $i--$ + \EndIf + \EndWhile + \State \Return $L$ + \EndFunction + \end{algorithmic} +\end{algorithm} + +\iffalse + +\begin{algorithm} + \caption{Recursive reconstruction of the longest common subsequence} + \begin{algorithmic}[1] + \Procedure{LCSQ}{$S_{1}$: Array($n$), $S_{2}$: Array($m$)} + \State $M, P \gets $ \Call{LCSQ\_Matrix}{$S_{1}$, $S_{2}$} + \State $i \gets n$ + \State $j \gets m$ + \State \Call{Aux}{$P$, $S_{1}$, $i$, $j$} + \EndProcedure + + \Procedure{Aux}{$P$: Array($n+1$, $m+1$), $S_{1}$: Array($n$), $i$, $j$} + \If {$P[i][j] = '\nwarrow' $} + \State $l \gets S_{1}[i]$ + \State \Call{Aux}{$P$, $S_{1}$, $i-1$, $j-1$} + \State \texttt{print}($l$) + \ElsIf {$P[i][j] = '\leftarrow'$} + \State \Call{Aux}{$P$, $S_{1}$, $i$, $j-1$} + \Else + \State \Call{Aux}{$P$, $S_{1}$, $i-1$, $j$} + \EndIf + \EndProcedure + \end{algorithmic} +\end{algorithm} +\fi diff --git a/content/chapters/part1/4.tex b/content/chapters/part1/4.tex index 77b4fd2..0f35a14 100644 --- a/content/chapters/part1/4.tex +++ b/content/chapters/part1/4.tex @@ -3,111 +3,114 @@ Let $S_{1} = \text{ATCTGAT}$ and $S_{2} = \text{TGCATA}$. In this case the longest common subsequence of $S_{1}$ and $S_{2}$ is $TCTA$. \begin{algorithm} - \caption{Construct a longest common subsequence matrix} - \begin{algorithmic}[1] - \Function{LCSQ\_Matrix}{$S_{1}$: Array($n$), $S_{2}$: Array($m$)} - \State $M \gets $ Array($m+1$, $n+1$) - \For{($i = 0$; $i < n+1$; $i++$)} - \For{$j = 0$; $j < m+1$; $j++$} - \If {$i = 0$ or $j = 0$} - \State $M[i][j] = 0$ - \Else - \If {$S_{1}[i] = S_{2}[j]$} - \State $match = M[i-1][j-1] + 1$ - \Else - \State $match = M[i-1][j-1]$ - \EndIf - \State $gap_{1} = M[i-1][j]$ - \State $gap_{2} = M[i][j-1]$ - \State $M[i][j] = \max \{ match, gap_{1}, gap_{2}\}$ - \EndIf - \EndFor - \EndFor - \State \Return $M$ - \EndFunction - \end{algorithmic} + \caption{Construct a longest common subsequence matrix} + \begin{algorithmic}[1] + \Function{LCSQ\_Matrix}{$S_{1}$: Array($n$), $S_{2}$: Array($m$)} + \State $M \gets $ Array($m+1$, $n+1$) + \For{($i = 0$; $i < n+1$; $i++$)} + \For{$j = 0$; $j < m+1$; $j++$} + \If {$i = 0$ or $j = 0$} + \State $M[i][j] = 0$ + \Else + \If {$S_{1}[i] = S_{2}[j]$} + \State $match = M[i-1][j-1] + 1$ + \Else + \State $match = M[i-1][j-1]$ + \EndIf + \State $gap_{1} = M[i-1][j]$ + \State $gap_{2} = M[i][j-1]$ + \State $M[i][j] = \max \{ match, gap_{1}, gap_{2}\}$ + \EndIf + \EndFor + \EndFor + \State \Return $M$ + \EndFunction + \end{algorithmic} \end{algorithm} \begin{algorithm} - \caption{Construct a longest common subsequence matrix keeping the path in memory} - \begin{algorithmic}[1] - \Function{LCSQ\_Matrix\_Path}{$S_{1}$: Array($n$), $S_{2}$: Array($m$)} - \State $M \gets $ Array($m+1$, $n+1$) - \State $P \gets $ Array($m+1$, $n+1$) - \For {($i = 0$; $i < n+1$, $i++$)} - \State $M[i][0] \gets 0$ - \EndFor - \For {($j = 0$; $j < m+1$; $j+$)} - \State $M[0][j] \gets 0$ - \EndFor - \For{($i = 1$; $i < n+1$; $i++$)} - \For{($j = 1$; $j < m+1$; $j++$)} - \If {$i = 1$ or $j = 0$} - \State $M[i][j] = 0$ - \Else - \If {$S_{1}[i-1] = S_{2}[j-1]$} - \State $M[i][j] \gets M[i-1][j-1] + 1$ - \State $P[i][j] \gets '\nwarrow'$ - \ElsIf {$M[i][j-1] \geq M[i-1][j]$} - \State $M[i][j] \gets M[i][j-1]$ - \State $P[i][j] \gets '\leftarrow'$ - \Else - \State $M[i][j] \gets M[i-1][j]$ - \State $P[i][j] \gets '\downarrow'$ - \EndIf - \EndFor - \EndFor - \State \Return $M, P$ - \EndFunction - \end{algorithmic} + \caption{Construct a longest common subsequence matrix keeping the path in memory} + \begin{algorithmic}[1] + \Function{LCSQ\_Matrix\_Path}{$S_{1}$: Array($n$), $S_{2}$: Array($m$)} + \State $M \gets $ Array($m+1$, $n+1$) + \State $P \gets $ Array($m+1$, $n+1$) + \For {($i = 0$; $i < n+1$, $i++$)} + \State $M[i][0] \gets 0$ + \EndFor + \For {($j = 0$; $j < m+1$; $j+$)} + \State $M[0][j] \gets 0$ + \EndFor + \For{($i = 1$; $i < n+1$; $i++$)} + \For{($j = 1$; $j < m+1$; $j++$)} + \If {$i = 1$ or $j = 0$} + \State $M[i][j] = 0$ + \Else + \If {$S_{1}[i-1] = S_{2}[j-1]$} + \State $M[i][j] \gets M[i-1][j-1] + 1$ + \State $P[i][j] \gets '\nwarrow'$ + \ElsIf {$M[i][j-1] \geq M[i-1][j]$} + \State $M[i][j] \gets M[i][j-1]$ + \State $P[i][j] \gets '\leftarrow'$ + \Else + \State $M[i][j] \gets M[i-1][j]$ + \State $P[i][j] \gets '\downarrow'$ + \EndIf + \EndIf + \EndFor + \EndFor + \State \Return $M, P$ + \EndFunction + \end{algorithmic} \end{algorithm} \begin{algorithm} - \caption{Backtrack the longest common subsequence} - \begin{algorithmic}[1] - \Function{LCSQ}{$S_{1}$: Array($n$), $S_{2}$: Array($m$)} - \State $M, P \gets $ \Call{LCSQ\_Matrix}{$S_{1}$, $S_{2}$} - \State $L \gets Array(M[n][m])$ - \State $k \gets 0$ - \State $i \gets n$ - \State $j \gets m$ - \While{$i > 0$ and $j > 0$} - \If {$P[i][j] = '\nwarrow' $} - \State $L[k] \gets S_{1}[i]$ - \State $i--$ - \State $j--$ - \State $k++$ - \ElsIf {$P[i][j] = '\leftarrow'$} - \State $j--$ - \Else - \State $i--$ - \EndIf - \EndWhile - \State \Return $L$ - \EndFunction - \end{algorithmic} + \caption{Backtrack the longest common subsequence} + \begin{algorithmic}[1] + \Function{LCSQ}{$S_{1}$: Array($n$), $S_{2}$: Array($m$)} + \State $M, P \gets $ \Call{LCSQ\_Matrix}{$S_{1}$, $S_{2}$} + \State $L \gets Array(M[n][m])$ + \State $k \gets 0$ + \State $i \gets n$ + \State $j \gets m$ + \While{$i > 0$ and $j > 0$} + \If {$P[i][j] = '\nwarrow' $} + \State $L[k] \gets S_{1}[i]$ + \State $i--$ + \State $j--$ + \State $k++$ + \ElsIf {$P[i][j] = '\leftarrow'$} + \State $j--$ + \Else + \State $i--$ + \EndIf + \EndWhile + \State \Return $L$ + \EndFunction + \end{algorithmic} \end{algorithm} -\begin{algorithm} - \caption{Recursive reconstruction of the longest common subsequence} - \begin{algorithmic}[1] - \Procedure{LCSQ}{$S_{1}$: Array($n$), $S_{2}$: Array($m$)} - \State $M, P \gets $ \Call{LCSQ\_Matrix}{$S_{1}$, $S_{2}$} - \State $i \gets n$ - \State $j \gets m$ - \State \Call{Aux}{$P$, $S_{1}$, $i$, $j$} - \EndProcedure +\iffalse + \begin{algorithm} + \caption{Recursive reconstruction of the longest common subsequence} + \begin{algorithmic}[1] + \Procedure{LCSQ}{$S_{1}$: Array($n$), $S_{2}$: Array($m$)} + \State $M, P \gets $ \Call{LCSQ\_Matrix}{$S_{1}$, $S_{2}$} + \State $i \gets n$ + \State $j \gets m$ + \State \Call{Aux}{$P$, $S_{1}$, $i$, $j$} + \EndProcedure - \Procedure{Aux}{$P$: Array($n+1$, $m+1$), $S_{1}$: Array($n$), $i$, $j$} - \If {$P[i][j] = '\nwarrow' $} - \State $l \gets S_{1}[i]$ - \State \Call{Aux}{$P$, $S_{1}$, $i-1$, $j-1$} - \State \texttt{print}($l$) - \ElsIf {$P[i][j] = '\leftarrow'$} - \State \Call{Aux}{$P$, $S_{1}$, $i$, $j-1$} - \Else - \State \Call{Aux}{$P$, $S_{1}$, $i-1$, $j$} - \EndIf - \EndProcedure - \end{algorithmic} -\end{algorithm} + \Procedure{Aux}{$P$: Array($n+1$, $m+1$), $S_{1}$: Array($n$), $i$, $j$} + \If {$P[i][j] = '\nwarrow' $} + \State $l \gets S_{1}[i]$ + \State \Call{Aux}{$P$, $S_{1}$, $i-1$, $j-1$} + \State \texttt{print}($l$) + \ElsIf {$P[i][j] = '\leftarrow'$} + \State \Call{Aux}{$P$, $S_{1}$, $i$, $j-1$} + \Else + \State \Call{Aux}{$P$, $S_{1}$, $i-1$, $j$} + \EndIf + \EndProcedure + \end{algorithmic} + \end{algorithm} +\fi diff --git a/content/chapters/part2/1.tex b/content/chapters/part2/1.tex index 8dc578d..6acf367 100644 --- a/content/chapters/part2/1.tex +++ b/content/chapters/part2/1.tex @@ -10,30 +10,37 @@ \State $M = $ Array($m+1$, $n+1$) \Comment{Initialize the matrix first column and first row} \State $P = $ Array($m$, $n$) \Comment{Store the direction of the cell we chose to build the next cell up on.} - \For {($i = 0$; $i < m+1$; $i++$)} - \State $M[i][0] = i * del(S_{1}[i])$ + \State $M[0][0] = 0$ + \For {($i = 1$; $i < m+1$; $i++$)} + \State $M[i][0] = M[i-1][0] + gap\_penalty$ \EndFor - \For {($j = 0$; $j < n+1$; $j++$)} - \State $M[0][j] = j * ins(S_{2}[j])$ + \For {($j = 1$; $j < n+1$; $j++$)} + \State $M[0][j] = M[0][j-1] + gap\_penalty$ \EndFor \Comment{Fill the remaining matrix} \For {($i = 1$; $i < m+1$; $i++$)} \For {($j = 1$; $j < n+1$; $j++$)} - \State $delete = M[i-1][j] + del(S_{1}[i-1])$ - \State $insert = M[i][j-1] + ins(S_{2}[j-1])$ + \State $delete = M[i-1][j] + gap\_penalty$ + \State $insert = M[i][j-1] + gap\_penalty$ \State $substitute = M[i-1][j-1] + sub(S_{1}[i-1], S_{2}[j-1])$ - \State $choice = \max \{delete, insert, substitute\}$ + \State $choice = \min \{delete, insert, substitute\}$ \If {$substitute = choice$} \State $P[i-1][j-1] = '\nwarrow'$ - \ElsIf {$insertion = choice$} - \State $P[i-1][j-1] = '\uparrow'$ - \Else + \ElsIf {$deletion = choice$} \State $P[i-1][j-1] = '\leftarrow'$ + \Else + \State $P[i-1][j-1] = '\uparrow'$ \EndIf \State $M[i][j] = choice$ \EndFor \EndFor \EndProcedure + \end{algorithmic} +\end{algorithm} + +\begin{algorithm} + \caption{Needleman-Wunsch Algorithm (Backtrack)} + \begin{algorithmic}[1] \Procedure{ShowAlignment}{$S_{1}$: Array($m$), $S_{2}$: Array($n$)} \State $extend_{1} = ''$ \State $extend_{2} = ''$ @@ -47,18 +54,92 @@ \State $j--$ \ElsIf {$P[i-1][j-1] = '\uparrow'$} \State $extend_{1} = S_{1}[i-1] \circ extend_{1}$ - \State $extend_{2} =\quad '-' \circ extend_{2}$ + \State $extend_{2} = '-' \circ extend_{2}$ \State $i--$ \Else - \State $extend_{1} =\quad '-' \circ extend_{1}$ + \State $extend_{1} = '-' \circ extend_{1}$ \State $extend_{2} = S_{2}[j-1] \circ extend_{2}$ \State $j--$ \EndIf \EndWhile + \While{$i > 0$} + \State $extend_{1} = S_{1}[i-1] \circ extend_{1}$ + \State $extend_{2} = '-' \circ extend_{2}$ + \State $i--$ + \State \Call{Insert}{0, $alignment$,$tuple$} + \EndWhile + \While{$j > 0$} + \State $extend_{1} = '-' \circ extend_{1}$ + \State $extend_{2} = S_{2}[j-1] \circ extend_{2}$ + \State $j--$ + \EndWhile \State \Call{print}{$extend_{1}$} \State \Call{print}{$extend_{2}$} \EndProcedure \State \Call{FillMatrix}{$S_{1}$, $S_{2}$} - \State \Call ShowAlignment($S_{1}$, $S_{2}$) + \State \Call{ShowAlignment}{$S_{1}$, $S_{2}$} + \end{algorithmic} +\end{algorithm} + +\begin{algorithm} + \caption{Needleman-Wunsch Algorithm (Backtrack) } + \begin{algorithmic}[1] + \Procedure{FillMatrix}{$S_{1}$: Array($m$), $S_{2}$: Array($n$)} + \State $M = $ Array($m+1$, $n+1$) + \State $P = $ Array($m$, $n$) + \Comment{Store the direction of the cell we chose to build the next cell up on.} + \State $M[0][0] = 0$ + \For {($i = 1$; $i < m+1$; $i++$)} + \State $M[i][0] = M[i-1][0] + gap\_penalty$ + \EndFor + \For {($j = 1$; $j < n+1$; $j++$)} + \State $M[0][j] = M[0][j-1] + gap\_penalty$ + \EndFor + \For {($i = 1$; $i < m+1$; $i++$)} + \For {($j = 1$; $j < n+1$; $j++$)} + \State $delete = M[i-1][j] + gap\_penalty$ + \State $insert = M[i][j-1] + gap\_penalty$ + \State $substitute = M[i-1][j-1] + sub(S_{1}[i-1], S_{2}[j-1])$ + \State $M[i][j] = \min \{substitute, insert, delete\}$ + \EndFor + \EndFor + \EndProcedure + \end{algorithmic} +\end{algorithm} + +\begin{algorithm} + \caption{Needleman-Wunsch Algorithm, using proper notation (Backtrack)} + \begin{algorithmic}[1] + \Procedure{BacktrackAlignment}{$S_{1}$: Array($m$), $S_{2}$: Array($n$)} + \State $alignment = LinkedList$ + \State $i = m$ + \State $j = n$ + \While{$i > 0$ and $j > 0$} + \If {$M[i-1][j-1] = M[i][j] - sub(S_{1}[i-1], S_{2}[j-1])$} + \State $tuple = \begin{pmatrix} S_{1}[i-1] \\ S_{2}[j-1] \end{pmatrix}$ + \State $i--$ + \State $j--$ + \ElsIf {$M[i-1][j-1] = M[i][j-1] - gap\_penalty$} + \State $tuple = \begin{pmatrix} S_{1}[i-1] \\ \varepsilon \end{pmatrix}$ + \State $i--$ + \Else + \State $tuple = \begin{pmatrix} \varepsilon \\ S_{2}[j-1] \end{pmatrix}$ + \State $j--$ + \EndIf + \State \Call{Insert}{0, $alignment$,$tuple$} + \EndWhile + \While{$i > 0$} + \State $tuple = \begin{pmatrix} S_{1}[i-1] \\ \varepsilon \end{pmatrix}$ + \State $i--$ + \State \Call{Insert}{0, $alignment$,$tuple$} + \EndWhile + \While{$j > 0$} + \State $tuple = \begin{pmatrix} \varepsilon \\ S_{2}[j-1] \end{pmatrix}$ + \State $j--$ + \State \Call{Insert}{0, $alignment$,$tuple$} + \EndWhile + \EndProcedure + \State \Call{FillMatrix}{$S_{1}$, $S_{2}$} + \State \Call{BacktrackAlignment}{$S_{1}$, $S_{2}$} \end{algorithmic} \end{algorithm} diff --git a/main.pdf b/main.pdf index ded9dcd..f9cf970 100644 --- a/main.pdf +++ b/main.pdf @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1f067fe2e3ed44151fc9477d9697bcf01e9d6c8fce05cc3a18c585382f4e54ae -size 313915 +oid sha256:129c003255cb3de4bdd4777c1ac9769a6b4cd1633a15cade1611eb3e8a2ad71a +size 333748 diff --git a/tmp.pdf b/tmp.pdf index 5abef09..9f6b6c3 100644 --- a/tmp.pdf +++ b/tmp.pdf @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7529f889933c1c9d295cab8160ff7aabdcef3a55f4a4e351822f1ce4dd86621c -size 61328 +oid sha256:bf9d5f869f3ee9e50f21d2cb73785aa5336477c399af4ce70ebaab1f4d6d557c +size 56195 diff --git a/tmp.tex b/tmp.tex index c619949..1b2b75b 100644 --- a/tmp.tex +++ b/tmp.tex @@ -11,6 +11,43 @@ \input{definitions.tex} \begin{document} + +\begin{algorithm} + \caption{Construct a longest common subsequence matrix keeping the path in memory} + \begin{algorithmic}[1] + \Function{LCSQ\_Matrix\_Path}{$S_{1}$: Array($n$), $S_{2}$: Array($m$)} + \State $M \gets $ Array($m+1$, $n+1$) + \State $P \gets $ Array($m+1$, $n+1$) + \For {($i = 0$; $i < n+1$, $i++$)} + \State $M[i][0] \gets 0$ + \EndFor + \For {($j = 0$; $j < m+1$; $j+$)} + \State $M[0][j] \gets 0$ + \EndFor + \For{($i = 1$; $i < n+1$; $i++$)} + \For{($j = 1$; $j < m+1$; $j++$)} + \If {$i = 1$ or $j = 0$} + \State $M[i][j] = 0$ + \Else + \If {$S_{1}[i-1] = S_{2}[j-1]$} + \State $M[i][j] \gets M[i-1][j-1] + 1$ + \State $P[i][j] \gets '\nwarrow'$ + \ElsIf {$M[i][j-1] \geq M[i-1][j]$} + \State $M[i][j] \gets M[i][j-1]$ + \State $P[i][j] \gets '\leftarrow'$ + \Else + \State $M[i][j] \gets M[i-1][j]$ + \State $P[i][j] \gets '\downarrow'$ + \EndIf +\EndIf + \EndFor + \EndFor + \State \Return $M, P$ + \EndFunction + \end{algorithmic} +\end{algorithm} + +\iffalse \begin{algorithm} \caption{Backtrack the longest common subsequence} \begin{algorithmic}[1] @@ -60,7 +97,7 @@ \EndProcedure \end{algorithmic} \end{algorithm} - +\fi \end{document} \end{document}