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;
  • 'acaacg\$'
  • 'caacg\$a'
  • 'aacg\$ac'
  • 'acg\$aca'
  • 'cg\$acaa'
  • 'g\$acaac'
  • '\$acaacg'
  1. 对S1到S7按字典序排序(\$字符的字典序最小),取每个串的最后一个字符,连成一个序列'gc\$aaac'。于是为BWT(S)='gc\$aaac'。
  • '\$acaacg'
  • 'aacg\$ac'
  • 'acaacg\$'
  • 'acg\$aca'
  • 'caacg\$a'
  • 'cg\$acaa'
  • 'g\$acaac'

也许,到这里,你还不清楚BWT变换和前缀树,有什么关系。那就接着往下看吧。

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

我们已经知道BWT(S)='gc\$aaac',对BWT(S)中的字符进行排序得到S'='\$aaaccg',得到下图形式的矩阵。

这个矩阵看起来,有些规律,但是又很奇怪。下面通过复原S的过程,我们来理解以下这个矩阵。

复原S

这个过程用语言描述比较麻烦,直接看图

按照图中(1)到(7)步,我们即可得到'$gcaaca',于是S='acaacg'。

其中,斜线表示是,我们找到最后一列的某个符号,然后跳至这个符号在第一列的位置。比如,在第(2)步中,最后一列为第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。

  1. 问题二:如何得到模式p在S中的位置?

匹配模式串之后,继续运行,直至\$,但是这样比较耗时。

另一种办法,在BWT串中记录相应的偏移。这种办法空间开销比较大,也可以采取类似于checkpoint的方法,记录部分的偏移。

四、待研究的问题

  1. 如何快速得到一个串的BWT编码?
  2. 如何允许部分匹配?

题外话

DNA比对还有一类快速的办法——使用哈希。

DNA比对算法:BWT的更多相关文章

  1. LeetCode-Repeated DNA Sequences (位图算法减少内存)

    Repeated DNA Sequences All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, ...

  2. 51nod 1445 变色DNA ( Bellman-Ford算法求单源最短路径)

    1445 变色DNA 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 有一只特别的狼,它在每个夜晚会进行变色,研究发现它可以变成N种颜色之一,将这些颜色标号为0,1 ...

  3. HDU1560 DNA sequence —— IDA*算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1560 DNA sequence Time Limit: 15000/5000 MS (Java/Oth ...

  4. 算法 - DNA搜索 - Ako Corasick

    场景:从很长的字符串(输入字符串.DNA)中搜索大量固定字符串(字典.基因) 题目:Determining DNA Health | HackerRank 算法:Aho–Corasick algori ...

  5. 字符串与模式匹配算法(六):Needleman–Wunsch算法

    一.Needleman-Wunsch 算法 尼德曼-翁施算法(英语:Needleman-Wunsch Algorithm)是基于生物信息学的知识来匹配蛋白序列或者DNA序列的算法.这是将动态算法应用于 ...

  6. 一个简单算法题引发的思考<DNA sorting>(about cin/template/new etc)

    首先是昨天在北京大学oj网上看到一个简单的算法题目,虽然简单,但是如何完成一段高效.简洁.让人容易看懂的代码对于我这个基础不好,刚刚进入计算机行业的小白来说还是有意义的.而且在写代码的过程中,会发现自 ...

  7. 利用Needleman–Wunsch算法进行DNA序列全局比对

    生物信息学原理作业第二弹:利用Needleman–Wunsch算法进行DNA序列全局比对. 具体原理:https://en.wikipedia.org/wiki/Needleman%E2%80%93W ...

  8. DNA binding motif比对算法

    DNA binding motif比对算法 2012-08-31 ~ ADMIN 之前介绍了序列比对的一些算法.本节主要讲述motif(有人翻译成结构模式,但本文一律使用基模)的比对算法. 那么什么是 ...

  9. 算法:POJ1007 DNA sorting

    这题比较简单,重点应该在如何减少循环次数. package practice; import java.io.BufferedInputStream; import java.util.Map; im ...

随机推荐

  1. js精确计算

    官方文档:http://mikemcl.github.io/big.js/ 使用方法: x = new Big(0.1); y = x.plus(0.2); // '0.3' var a=Big(0. ...

  2. java中的i++和++i区别

    public class Main { public static void main(String[] args) { int i = 0; i = i++; System.out.println( ...

  3. poptest老李谈动态口令原理

    poptest老李谈动态口令原理     poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:908 ...

  4. C#, VB.NET如何加密PDF文档

    在日常工作中,人们通常通过加密PDF文档的方式来保护PDF文档.不管是公司还是个人,使用PDF加密术来设置一些权限是必不可少的.为了使PDF文档既可读又不能被未授权的用户所更改,一份PDF文档往往需要 ...

  5. java调试技能之dubbo调试 ---telnet

    dubbo作为一个远程调用框架,虽与同类型的框架,不知道谁优谁劣,但是就公司层面使用来说,还是很棒的.这里简单的写一下怎么使用和调试技巧,就算是作个使用总结吧,供快速使用和问题解决! dubbo是基于 ...

  6. C#遍历指定文件夹中的所有文件(转)

    原文链接:http://www.cnblogs.com/qianqianfy/archive/2009/07/08/1518974.html 1. C#遍历指定文件夹中的所有文件 DirectoryI ...

  7. 关于block使用的几点注意事项

    1.在使用block前需要对block指针做判空处理. 不判空直接使用,一旦指针为空直接产生崩溃. if (!self.isOnlyNet) { if (succBlock == NULL) { // ...

  8. ConcurrentHashMap总结

    线程不安全的HashMap 因为多线程环境下,使用HashMap进行put操作会引起死循环,导致CPU利用率接近100%,所以在并发情况下不能使用HashMap,如以下代码   final HashM ...

  9. NestedScrollView嵌套RecycleView 滑动 实现上滑隐藏 下滑显示头部效果

    废了好大的劲才弄好的,记下来 方便以后查看 public class MainActivity extends AppCompatActivity { private RecyclerView mRe ...

  10. 编译MangosZero

    最近研究了一下魔兽世界模拟器MangosZero,花了两天时间终于编译成功!现在把编译的过程做个完整的记录,以便让想要学习编译的同学们少走弯路! 服务器端运行界面: 客户端运行界面: 一:下载源程序 ...