Smith-Waterman演算法及其Java實現

來源:互聯網
上載者:User

標籤:stream   賦值   sem   最大   print   new   blog   for   put   

Smith-Waterman演算法是1981年Smith和Waterman提出的一種用來尋找並比較具有局部相似性地區的動態規划算法,很多後來的演算法都是在該演算法的基礎上發展的。這是一種兩序列局部比對演算法,把兩條未知的序列進行排列,通過字母的匹配,刪除和插入操作,使得兩條序列達到同樣長度,在操作的過程中,儘可能保持相同的字母對應在同一個位置。當兩條序列進行比對時,找出待比對序列中的某一子片段的最優比對。這種比對方法可能會揭示一些匹配的序列段,而本來這些序列段是被一些完全不相關的殘基所淹沒的。


其演算法過程簡單描述為:
1) 為每一堿基對或殘基對賦值。相同或類似的賦予正值,對於不同的或有空位的賦予負值;
2) 用0對矩陣邊緣單元初始化;
3) 矩陣中得分值相加,任何小於0的得分值均用0代替;
4) 通過動態規劃的方法,從矩陣中的最大分值單元開始回溯尋找;
5) 繼續,一直到分值為0的單元停止,此回溯路徑的單元即為最優比對序列。
由以上可知,Smith-Waterman演算法主要分兩步.計算得分矩陣和尋找最佳相似片段對。得到得分矩陣以後,用動態規劃回溯的方法找到局部最大相似片段對:先找到得分矩陣中最大的元素.然後按照元素原路徑一步一步往前回溯,直到回溯到0時停止。

 

下面舉例子來說明,這個例子也來源於Smith-Waterman的論文原文。
1) 我們假設需要匹配的兩個序列分別為s1=AAUGCCAUUGACGG,S2=ACAGCCUCGCUUAG。
2) 首先,計算匹配度矩陣H。找到矩陣中得分最大(3.3)的元組H(10,8),開始回溯的過程。
3) 回溯的思路很簡單,就是檢查位於該元組上方,左方,和左上方的元組,看它的得分是等於上-4/3,還是左-4/3,還是左上+1,還是左上-1/3。簡而言之,就是看看這個元組是“從誰那兒走過來的”。
4) 回溯終止的臨界條件是,某個元組的得分為0,這意味著我們尚未找到匹配這兩個串的子串頭。
5) 整個回溯過程結束後,找到的子串如下:

AAUGCCAUUG
ACAGCC-UCG

下面是用Java語言寫的原始碼:

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.Iterator;import java.util.Stack;public class SWSq {    private int[][] H;    private int[][] isEmpty;    private static int SPACE ;                      //空格匹配的得分      private static int MATCH ;                       //兩個字母相同的得分      private static int DISMACH;                    //兩個字母不同的得分      private int maxIndexM, maxIndexN;    private Stack<Character> stk1, stk2;    public String subSq1, subSq2;                        //相似性最高的兩個子串      public SWSq(){        stk1 = new Stack<Character>();        stk2 = new Stack<Character>();        SPACE = -4;        MATCH = 3;        DISMACH = -1;    }    private int max(int a, int b, int c){        int maxN;        if(a >= b)            maxN = a;        else            maxN = b;        if(maxN < c)            maxN = c;        if(maxN < 0)            maxN = 0;        return maxN;    }    private void calculateMatrix(String s1, String s2, int m, int n){//計算得分矩陣          if(m == 0)            H[m][n] = 0;        else if(n == 0)            H[m][n] = 0;        else{            if(isEmpty[m - 1][n - 1] == 1)                calculateMatrix(s1, s2, m-1, n-1);            if(isEmpty[m][n - 1] == 1)                calculateMatrix(s1, s2, m, n-1);            if(isEmpty[m - 1][n] == 1)                calculateMatrix(s1, s2, m-1, n);            if(s1.charAt(m-1) == s2.charAt(n-1))                H[m][n] = max(H[m - 1][n - 1] + MATCH, H[m][n - 1] + SPACE, H[m - 1][n] + SPACE);            else                H[m][n] = max(H[m - 1][n - 1] + DISMACH, H[m][n - 1] + SPACE, H[m - 1][n] + SPACE);        }        isEmpty[m][n] = 0;    }    private void findMaxIndex(int[][] H, int m, int n){//找到得分矩陣H中得分最高的元組的下標          int curM, curN, i, j, max;        curM = 0;        curN = 0;        max = H[0][0];        for(i = 0; i < m; i++)            for(j = 0; j < n; j++)                if(H[i][j] > max){                    max = H[i][j];                    curM = i;                    curN = j;                }        maxIndexM = curM;        maxIndexN = curN;    }    private void traceBack(String s1, String s2, int m, int n){//回溯 尋找最相似子序列          if(H[m][n] == 0)            return;        if(H[m][n] == H[m-1][n] + SPACE) {            stk1.add(s1.charAt(m-1));            stk2.add(‘-‘);            traceBack(s1, s2, m - 1, n);        }        else if(H[m][n] == H[m][n-1] + SPACE) {            stk1.add(‘-‘);            stk2.add(s2.charAt(n-1));            traceBack(s1, s2, m, n - 1);        }        else {            stk1.push(s1.charAt(m - 1));            stk2.push(s2.charAt(n-1));            traceBack(s1, s2, m - 1, n - 1);        }    }    public String ALtoString(ArrayList<Character> A) {        StringBuilder sb = new StringBuilder();        for (Character a : A) {            sb.append(a.toString());        }        return sb.toString();    }    public void find(String s1, String s2){        //initMatrix(s1.length(), s2.length());          int i, j;        H = new int[s1.length() + 1][s2.length() + 1];        isEmpty = new int[s1.length() + 1][s2.length() + 1];        for(i = 0; i<=s1.length(); i++)            for(j = 0; j<=s2.length(); j++)                isEmpty[i][j] = 1;        calculateMatrix(s1, s2, s1.length(), s2.length());        findMaxIndex(H, H.length, H[0].length);        traceBack(s1, s2, maxIndexM, maxIndexN);        ArrayList<Character> arr1 = new ArrayList<>();        ArrayList<Character> arr2 = new ArrayList<>();        while(!stk1.empty())            arr1.add(stk1.pop());        subSq1 = ALtoString(arr1);        while(!stk2.empty())            arr2.add(stk2.pop());        subSq2 = ALtoString(arr2);    }    public static void main(String[] args) throws IOException {        SWSq x = new SWSq();        String s1 = "AAUGCCAUUGACGG";        String s2 = "ACAGCCUCGCUUAG";        x.find(s1, s2);        System.out.println("----------------------------");        System.out.println(s1);        System.out.println(s2);        System.out.println("----------------------------");        System.out.println(x.subSq1);        System.out.println(x.subSq2);    }}  

  

 

Smith-Waterman演算法及其Java實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.