Smith-Waterman算法及其Java实现
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实现的更多相关文章
- smith waterman算法
http://www.360doc.com/content/14/0106/00/14641369_342933143.shtml
- DNA序列局部比对(Smith–Waterman algorithm)
生物信息原理作业第三弹:DNA序列局部比对,利用Smith–Waterman算法,python3.6代码实现. 实例以及原理均来自https://en.wikipedia.org/wiki/Smith ...
- [Sequence Alignment Methods] Smith–Waterman algorithm
Smith–Waterman algorithm 首先需要澄清一个事实,Smith–Waterman algorithm是求两个序列的最佳subsequence匹配,与之对应的算法但是求两个序列整体匹 ...
- 对一致性Hash算法,Java代码实现的深入研究
一致性Hash算法 关于一致性Hash算法,在我之前的博文中已经有多次提到了,MemCache超详细解读一文中"一致性Hash算法"部分,对于为什么要使用一致性Hash算法.一致性 ...
- 常见排序算法(附java代码)
常见排序算法与java实现 一.选择排序(SelectSort) 基本原理:对于给定的一组记录,经过第一轮比较后得到最小的记录,然后将该记录与第一个记录的位置进行交换:接着对不包括第一个记录以外的其他 ...
- 几大排序算法的Java实现
很多的面试题都问到了排序算法,中间的算法和思想比较重要,这边我选择了5种常用排序算法并用Java进行了实现.自己写一个模板已防以后面试用到.大家可以看过算法之后,自己去实现一下. 1.冒泡排序:大数向 ...
- 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化
上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来 ...
- 7种基本排序算法的Java实现
7种基本排序算法的Java实现 转自我的Github 以下为7种基本排序算法的Java实现,以及复杂度和稳定性的相关信息. 以下为代码片段,完整的代码见Sort.java 插入排序 /** * 直接插 ...
- 利用朴素贝叶斯算法进行分类-Java代码实现
http://www.crocro.cn/post/286.html 利用朴素贝叶斯算法进行分类-Java代码实现 鳄鱼 3个月前 (12-14) 分类:机器学习 阅读(44) 评论(0) ...
- 【LeetCode-面试算法经典-Java实现】【053-Maximum Subarray(最大子数组和)】
[053-Maximum Subarray(最大子数组和)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Find the contiguous subarray w ...
随机推荐
- 问题 C: 质因数的个数
1947: 质因数的个数 时间限制: 1 Sec 内存限制: 32 MB提交: 245 解决: 114[提交][状态][讨论版][命题人:外部导入] 题目描述 求正整数N(N>1)的质因数的 ...
- LeetCode 389——找不同
1. 题目 2. 解答 2.1. 方法一 将 s 和 t 转化为 Python 的列表,然后遍历列表 s 的元素,将它们从列表 t 中删除,最后列表 t 中会余下一个元素,即为所求. class So ...
- 数论初步——Eratosthenes筛法
具体内容见紫书p312-p313 一.用Eratosthenes筛法构造1~n的素数表 思想:对于不超过n的每个非负整数p,删除2p,3p,4p…,当处理完所有的数后,还没有被删除的就是素数. 代码: ...
- direct.h头文件(对目录操作)
chdir()改变当前目录的函数原形:int chdir(const char *path)功能:把由path指定的目录改为当前目录.path参数中可以指定驱动器号,如“a:\\ddd”, 但只是改变 ...
- android仿QQ的SlideMenu
这其实很简单就可以实现,只需要自定义一个View继承自HorizontalScrollView 1,新建一个项目,再新建一个MySlideMenu继承HorizontalScrollView publ ...
- 【SSH】——spring的控制反转和依赖注入
spring是一个轻量级的容器框架,主要是为了使企业的开发变得简单.高效.无论是从大小还是开销来讲,他都可以算是轻量级的,也是非侵入性的. 下图是spring的框架示意图,说到spring,就不得不提 ...
- Aspose.Pdf合并PDF文件
使用Aspose.Pdf类库,有很多种方法可以合并PDF文件,这里简单介绍小生见到的几种: Doucment.Pages.Add PdfFileEditor.Append PdfFileEditor. ...
- P4016 负载平衡问题
题目描述 G 公司有 n 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使 n个仓库的库存数量相同.搬运货物时,只能在相邻的仓库之间搬运. 输入输出格式 输入格式: 文 ...
- hihocoder 1323 回文字符串(字符串+dp)
题解: 比较水的题目 dp[i][j]表示[i...j]最少改变几次变成回文字符串 那么有三种转移 dp[i][j] = dp[i+1][j-1] + s[i] != s[j] dp[i][j] = ...
- AGC016C +/- Rectangle(构造)
题目大意:给定H,W,h,w四个数,求是否满足矩阵的全部数之和和正数,h行w列之和为负数 如果h和w恰好是H,W的约数,则肯定不存在 否则肯定存在 只需要把h,w内每个元素填的足够大,然后小矩形的最后 ...