繁体   English   中英

DNA比对-分数是否相加?

[英]DNA alignment — score is additive or not?

所以我有一个递归代码,可以为2条DNA链提供最佳的比对,但问题是它的执行速度非常慢(我需要递归)。 然后,我在麻省理工学院的网站上看到结果是可加的,这对我来说非常好,但后来我想了一下,发现存在问题:

网站: http//ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-096-algorithms-for-computational-biology-spring-2005/lecture-notes/lecture5_newest.pdf

麻省理工学院网站说,对于给定的spilt(i,j):first_strand(0,i)和second_strand(0,j)对齐
+ first_strand(i,len)和second_strand(j,len)对齐

等于

第一链和第二链对齐

但:

GTC GTAA

GTA对齐的G为G-,A对齐的GTA TC为TC和A-结果= G--TC和GTAA-

真正的最佳成绩= GTC- GTAA

任何人都可以在MIT网站上解释它们的意思吗? 我可能全都错了!

我认为您正在谈论此链接

如果是这样,请非常仔细地阅读数百遍;-)如果您考虑将拆分固定在特定(i, j)对上的比对那么它是“加法”的。

在您所假设的反例中,您首先打破了GTC的初始GGTAA的初始GTA 那么G--是将GTC更改为G的最短方法。 精细。 继续进行相同的拆分,您仍然需要对齐其余的右侧部分: TCA 还可以

并不是说这是最好的分割方法。 考虑到您只考虑特定的拆分,因此只能说这是最好的对齐方式。

这是动态编程方法中的一小步,这是您缺少的部分。 仍然需要计算所有可能的拆分中的最佳比对。

首先,动态编程很棘手。 您不应该期望通过凝视电报幻灯片来学习它。 阅读一本真正的教科书,或在网上搜索教程。

加快递归版本

注释指示此“必须”的代码是递归的。 那好吧 ;-)

警告:我只是将其结合起来以说明加快合适的递归函数的一般过程。 几乎没有经过测试。

首先是一个非常幼稚的递归版本:

def lev(a, b):
    if not a:
        return len(b)
    if not b:
        return len(a)
    return min(lev(a[:-1], b[:-1]) + (a[-1] != b[-1]),
               lev(a[:-1], b) + 1,
               lev(a, b[:-1]) + 1)

在这里讨论的所有运行中,我将使用"absd31-km""ldk3-1fjm"作为参数。

在我的盒子上,使用Python 3,该简单函数在约1.6秒后返回7。 这是可怕的慢。

最明显的问题是不断重复的字符串切片。 索引中的每个:与所切字符串的当前长度成正比的时间。 因此,第一个改进是改为传递字符串索引。 由于代码总是切掉字符串的前缀,因此我们只需要传递“字符串结尾”索引:

def lev2(a, b):
    def inner(j1, j2):
        if j1 < 0:
            return j2 + 1
        if j2 < 0:
            return j1 + 1
        return min(inner(j1-1, j2-1) + (a[j1] != b[j2]),
                   inner(j1-1, j2) + 1,
                   inner(j1, j2-1) + 1)
    return inner(len(a)-1, len(b)-1)

好多了! 此版本“仅”在大约1.44秒内返回7。 仍然非常缓慢,但比原始版本要好。 较长的琴弦会增加它的优势,但谁在乎;-)

我们快完成了! 现在要注意的重要一点是,函数在运行过程中多次传递相同的参数。 我们在“备忘”中捕获了这些内容,以避免所有多余的计算:

def lev3(a, b):
    memo = {}
    def inner(j1, j2):
        if j1 < 0:
            return j2 + 1
        if j2 < 0:
            return j1 + 1
        args = j1, j2
        if args in memo:
            return memo[args]
        result = min(inner(j1-1, j2-1) + (a[j1] != b[j2]),
                     inner(j1-1, j2) + 1,
                     inner(j1, j2-1) + 1)
        memo[args] = result
        return result
    return inner(len(a)-1, len(b)-1)

该版本在大约0.00026秒内返回7,比lev2快5000倍。

现在,如果您已经研究了基于矩阵的算法并斜视了一下,您将看到lev3() 有效地构建了二维矩阵映射索引对,以在其memo字典中生成结果。 它们实际上是同一回事,除了递归版本以更复杂的方式构建矩阵。 另一方面,递归版本可能更易于理解和推理。 请注意,您发现的幻灯片将记忆孔隙称为“自上而下”,而嵌套循环矩阵的方法则“自下而上”。 这些很好地描述了。

关于递归函数的工作原理,您什么都没有说,但是如果递归函数遇到任何类似的过度,您应该可以使用类似的技术获得类似的加速效果:-)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM