用于在两个非常长的文本序列中查找唯一集的快速算法

时间:2010-08-27 02:43:58

标签: algorithm performance dna-sequence

我需要比较X和Y染色体的DNA序列,并找到Y染色体独有的模式(由大约50-75个碱基对组成)。注意,这些序列部分可以在染色体中重复。这需要快速完成(BLAST需要47天,需要几个小时或更短时间)。是否有任何算法或程序特别适合这种比较?同样,速度是关键。

我把它放在SO上的原因之一是从特定应用领域之外的人那里获得视角,他们可以提出他们在日常使用中用于字符串比较的算法,这可能适用于我们的使用。所以不要害羞!

4 个答案:

答案 0 :(得分:3)

  1. 在序列X上构建suffix tree S。
  2. 对于序列Y中的每个起始位置i,在S中查找字符串Y [i..i + 75]。如果从位置i开始不能找到匹配(即,如果在j <75核苷酸匹配后查找失败)然后你找到了Y独有的长度为j的字符串。
  3. 所有起始位置上最小的字符串i是最短的唯一字符串(或者如果您对最小化长度不感兴趣,则在找到任何此类字符串后暂停)。
  4. 总时间:O(| X | + m | Y |)其中m是最大字符串长度(例如m = 75)。

    基于广义后缀树,可能有更高效的算法。

答案 1 :(得分:2)

我假设你有一个X和一个Y来比较。将它们连接起来,由未出现在任何一个中的标记字符分隔,以形成例如XOY。现在在线性时间内形成http://en.wikipedia.org/wiki/Suffix_array

你得到的是一个指向连接字符串中位置的指针数组,其中指针的排列使得它们指向的子字符串在数组中按字母顺序出现。您还获得了一个LCP数组,给出了后缀与数组之前的后缀之间共享的最长公共前缀的长度,该后缀的排序小于它。这实际上是在该位置和小于它的ANY子串之间共享的最长公共前缀,因为具有较长公共前缀且小于string [i]的任何内容将在它与当前字符串[i-1]之间进行排序。

你可以告诉指针从其位置指向哪个原始字符串,因为X在Y之前。你可以将数组切割成X和Y指针的交替子部分。 pos [i]和pos [i - 1]之间共享的公共前缀的长度是lcp [i]。 pos [i]和pos [i-2]之间共享的前缀长度为min(lcp [i],lcp [i-1])。因此,如果您在Xs范围之前的Y值处开始,您可以通过逐步删除该部分,在每一步执行最小操作来计算出Y和所有X之间的前缀字符数。类似地,你可以计算出所有这些X之间共享的前缀字符数和后缀数组中接下来出现的Y,每个X的成本为1分钟。同样,当然是Y范围。现在,每个条目最多可以计算X(或Y)中每个位置与Y(或X)中任何位置之间共享的最长前缀。

我认为你想要X或Y中的子串在它和其他性别的任何其他子串之间共享小前缀,因为从同一位置开始比一个字符长一个字符的字符串不会出现在另一个性别中一点都不我想一旦你完成了上面的min()计算,你就可以使用堆来提取N个最小的前缀子串,以跟踪N个最小的条目。我认为这里的所有内容都需要时间线性| X | + | Y | (除非N与| X |或| Y |相当)。

答案 2 :(得分:1)

这个paper可能有一些替代方法可以调整BLAST来改善其性能(通过细分问题空间AFAIKS)。

答案 3 :(得分:0)

我有一个有趣的答案,它将是技术性的。主要思想是应该在GPU上进行子序列的比较,因为现代视频卡的GPU是高度并行的处理环境(如小型超级计算机)。 所以我们可以将碱基对编码为一个像素,假设X染色体是1.54亿对 - 我们得到一个包含1.54亿像素的X染色体图像 - 这个图像大小约为500 MB。对于Y染色体,我们得到160 MB大小的图像。 因此,这两个(500 + 160)MB图像可以非常有效地由血统视频卡处理。 (只需获得一张&gt; = 1 GB视频内存的视频卡。)

下一步是编写GPU程序,可能借助于Pixel ShaderCudaOpenCL

GPU程序很简单 - 基本上它会将Y染色体图像中的50-75个相邻像素与X染色体图像的所有像素进行比较。因此,这个GPU程序最多应该有75 * 1.54亿个操作,这将在现代GPU上计算一小时左右。因为Y的所有子序列都将被并行测试。

希望有所帮助