DNA比對算法:BWT



BWT算法,實質上是前綴樹的一種實現。那么什么是前綴樹呢?

一、前綴樹

對於問題p in S?如果S=rpq,那么p為S前綴rp的一個后綴。

於是,為了判斷p in S 是否成立,我們找到S的所有前綴,然后逐一判斷p是不是它們的后綴。為了加快效率,我們將所有的前綴建成一顆樹,這棵樹便是前綴樹。下面,我們舉例說明前綴樹的建立過程和如何使用前綴樹進行模式匹配。

前綴樹的建立

假設S='acaacg',p='aac',那么我們首先找到S的所有前綴,如下

  • a
  • ac
  • aca
  • acaa
  • acaac
  • acaacg

於是,我們將這些前綴翻轉過來,然后建立為一顆字典樹,如下圖
此處輸入圖片的描述

模式匹配

\(p='aac'\),令\(p'=caa\)(即p的翻轉)。顯然,現在只需進行一次樹的搜索,即可完成匹配。

如果在判斷p in S 的同時,還需要得到p 在S 中的位置,那么只需在建樹的時候,將每個字符的索引加上,例如
此處輸入圖片的描述
當然,也可以不保存索引,每次模式匹配結束時,沿着當前節點走下去,一直到為S[0]。

在節點中添加數字,有其他用處,詳見我的另一篇博文廣義后綴樹的簡介

評價

我們可以看到,相對於常規的匹配算法,前綴樹時間復雜度比較小,但占用空間較大。下面要說的BWT算法,就是解決這個問題的。

二、構建BWT(S)

仍然,以S='acaacg'為例。

1.令S1=S+'$'='acaacg$';
2.循環左移S1 6次,得到S2,S3,S4,S5,S6,S7;

3.對S1到S7按字典序排序(\(\$\)字符的字典序最小),取每個串的最后一個字符,連成一個序列\('gc\$aaac'\)。於是為\(BWT(S)='gc\$aaac'\)

也許,到這里,你還不清楚BWT變換和前綴樹,有什么關系。那就接着往下看吧。

三、使用BWT,進行模式匹配

我們已經知道BWT(S)=\('gc\$aaac'\),對BWT(S)中的字符進行排序得到\(S'='\$aaaccg'\),得到下圖形式的矩陣。

此處輸入圖片的描述

這個矩陣看起來,有些規律,但是又很奇怪。下面通過復原S的過程,我們來理解以下這個矩陣。

復原S

這個過程用語言描述比較麻煩,直接看圖

此處輸入圖片的描述

按照圖中(1)到(7)步,我們即可得到'$gcaaca',於是S='acaacg'。

其中,斜線表示是,我們找到最后一列的某個符號,然后跳至這個符號在第一列的位置。比如,在第(3)步中,最后一列為第2個c,我們跳到第一行中第2個c的位置。

模式匹配

p='aac',令\(p'='caa'\),選取c作為起點,由於S中有兩個c,因此有兩種可能 的匹配。

  1. 從第一個c出發
    此處輸入圖片的描述
  2. 從第二個c出發
    此處輸入圖片的描述
    因此,在方案2得到p',因此p in S是正確的。

幾個問題
1.問題一:如何得到某個符號,在本列中是第幾個?

顯然,我們可以使用一個數組來保存。例如,對於'$gcaaca',數組a=[1,1,1,1,2,2,3]。

$ g c a a c a
[1,1,1,1,2,2,3]

但是,還有一種省空間的辦法。我們只保存串'$gcaaca'中某些字符的位置,這些字符我們稱為checkpoint。

2.問題二:如何得到模式p在S中的位置?

匹配模式串之后,繼續運行,直至$,但是這樣比較耗時。

另一種辦法,在BWT串中記錄相應的偏移。這種辦法空間開銷比較大,也可以采取類似於checkpoint的方法,記錄部分的偏移。

四、待研究的問題

  1. 如何快速得到一個串的BWT編碼?
  2. 如何允許部分匹配?

題外話

DNA比對還有一類快速的辦法——使用哈希。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM