Needleman-Wunsch算法在基因组序列比对中的实战应用

生物信息学(1)——双序列比对之Needleman-Wunsch(NW)算法详解及C++实现 1. 什么是序列比对 所谓的序列比对,就是两个或者多个序列按照碱基排列进行比较,从而反映片段之间的相似性和阐明序列的同源性。这里主要是将未知功能的序列与已知序列进行比对,从而确定序列分析。序列比对的基本思想是,基于生物学中序列决定结构,结构决定功能的普遍规律,将核酸序列和蛋白质一级结构上的序列都看成由基本字符组成的字符串,检测序列之间的相似性,发现生物序列中的功能、结构和进化的信息 2. 引入序列比对的原因 对于两种相似的序列,DNA复制一共有三种情况可能导致两个序列不同: (1)SNP(单核苷酸多态性), 阅读详情

1. 从“找茬游戏”到基因组比对:为什么我们需要Needleman-Wunsch?

如果你玩过“大家来找茬”或者“连连看”,那你其实已经接触过“比对”的核心思想了——在两幅看似相同的图片里找出细微的差异,或者把两个相同的图案连接起来。在生物信息学里,我们面对的是生命最基本的“字母表”:A、T、C、G(对于DNA)。基因组序列比对,简单说,就是把两条长长的、由这四个字母组成的“生命天书”摆在一起,看看它们哪里相同,哪里不同。

这听起来好像挺简单?但实际操作起来,挑战巨大。想象一下,你有两篇由这四个字母随机写成的、长度可能达到数十亿字符的文章,其中一篇可能中间插入了几个无关的段落(插入),或者删掉了几句话(缺失),还有些句子里的单词被替换了(突变)。你的任务不仅仅是找出完全相同的句子,还要在允许插入、缺失和替换的前提下,找到让这两篇文章“对齐”得最好的方式。这个“最好”需要一个标准来评判,这就是得分矩阵(Scoring Matrix)和空位罚分(Gap Penalty)。匹配了加分,错配或引入空位(代表插入或缺失)则扣分。最终目标,是找到一个全局性的对齐方案,使得总得分最高。

这就是Needleman-Wunsch算法大显身手的地方。它由Saul B. Needleman和Christian D. Wunsch在1970年提出,是第一个真正意义上解决全局序列比对问题的动态规划算法。所谓“全局”,就是要求比对必须覆盖两条序列的全部长度,从第一个字母到最后一个字母,都要参与比对。这非常适合用来比较同源基因、研究物种间的进化关系,或者评估一个测序结果与参考基因组的整体相似性。

我刚开始接触生物信息分析时,总觉得算法高深莫测。但后来发现,Needleman-Wunsch的核心思想非常直观,就像我们规划从家到公司的最优路线一样。你可能会考虑:是直接走大路(匹配),还是绕个小巷子(错配),或者因为修路不得不绕一大圈(插入空位)?算法做的就是系统地评估所有可能的“路线”(比对路径),然后找出那条“最快”(得分最高)的。对于刚入门的小伙伴,别被“动态规划”这个词吓到,接下来我会用最直白的语言和具体的代码,带你亲手实现它,并看看在真实的基因组数据分析中怎么用它、怎么调参。

2. 算法核心:拆解动态规划的“填表游戏”

Needleman-Wunsch算法的精髓,可以用一个“填表格”的游戏来理解。这个表格就是我们常说的动态规划矩阵(DP矩阵)。

2.1 构建你的得分地图

假设我们要比对的序列是:

  • S1: GCCCTAGCG
  • S2: GCGCAATG

我们把序列S1的字符放在表格的顶部(列),S2的字符放在表格的左侧(行)。表格中的每一个格子 dp[i][j] 记录了一个关键信息:序列S1的前j个字符与序列S2的前i个字符进行全局比对时,能获得的最高得分。

首先,我们需要设定游戏规则(计分方案):

  • 匹配(Match):当上下两个字符相同时,比如S1的‘G’对上S2的‘G’,奖励+1分。
  • 错配(Mismatch):当上下两个字符不同时,比如‘C’对上‘A’,惩罚-1分。
  • 空位(Gap):当一条序列的字符需要与另一条序列的“空白”(用‘_’表示)对齐时,代表发生了插入或缺失,惩罚-2分。这是一个线性空位罚分模型。

表格的第一行和第一列需要初始化。这代表了一条序列为空时,与另一条序列前缀比对的情况。例如,第一行表示S2为空序列,S1的每个字符都只能与空位对齐,所以分数是累加的 -2。初始化后,我们就有了计算的起点。

2.2 状态转移:当前得分从何而来?

对于表格内的任何一个格子 dp[i][j],我们计算它的得分时,只可能有三种“来源”:

  1. 从左上角来(对角移动):这意味着我们让 S1[j] 和 S2[i] 这两个字符直接对齐。那么得分就是 dp[i-1][j-1] 的分数,加上这两个字符比对的结果(匹配+1或错配-1)。
  2. 从左边来(水平移动):这意味着我们让 S1[j] 这个字符去和S2的一个“空位”对齐。相当于在S2中插入了一个空位来匹配S1的字符。那么得分就是 dp[i][j-1] 的分数,加上一个空位罚分(-2)。
  3. 从上方来(垂直移动):这意味着我们让 S2[i] 这个字符去和S1的一个“空位”对齐。相当于在S1中插入了一个空位。那么得分就是 dp[i-1][j] 的分数,加上一个空位罚分(-2)。

dp[i][j] 的值,就是这三种可能来源中得分最高的那一个。 用公式表示就是: dp[i][j] = max( 对角得分, 左方得分-2, 上方得分-2 )

这个步骤就是动态规划的“状态转移方程”。我们一行一行、一列一列地填充整个表格,最终,表格最右下角的那个格子 dp[长度S2][长度S1] 的值,就是我们追求的全局最高比对得分。

2.3 回溯:找出最优的比对路径

光知道最高分还不够,我们得知道具体是怎么比对的。这就需要我们在填表的同时,用一个额外的回溯矩阵(Traceback Matrix) 来记录每个格子得分的来源。比如,用数字1代表来自左上角,2代表来自左边,4代表来自上边。

填完表后,我们从终点(右下角)开始,根据回溯矩阵记录的“来时路”,一步一步倒退回起点(左上角)。这个回溯路径就对应了一条最优的比对方案:

  • 如果是从左上角来的,就将S1和S2的当前字符对齐输出。
  • 如果是从左边来的,就将S1的当前字符与一个空位‘_’对齐。
  • 如果是从上边来的,就将S2的当前字符与一个空位‘_’对齐。

有时候,在某个格子可能会有多个来源都能达到相同的最高分,这就意味着存在多条最优比对路径,即多个同样好的全局比对方案。好的算法实现应该能找出所有这些可能。

3. 手把手代码实战:用Java实现并解读结果

理论说再多,不如亲手跑一遍代码来得实在。下面我基于原始文章的Java代码框架,给你做一个更详细的、带注释的拆解,并分享一些我调试时踩过的坑。

import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;

public class GlobalSequenceAlignment {

    private String seq1, seq2; // 待比对的两条序列
    private int len1, len2;    // 序列长度
    private int[][] scoreMatrix; // 得分矩阵(DP表)
    private int[][] traceback;   // 回溯矩阵,记录路径来源
    private List<String> alignmentsSeq1; // 存储所有最优比对的序列1结果
    private List<String> alignmentsSeq2; // 存储所有最优比对的序列2结果

    // 计分参数 - 这里我们可以灵活调整!
    private int matchScore = 1;
    private int mismatchPenalty = -1;
    private int gapPenalty = -2;

    public GlobalSequenceAlignment(String s1, String s2) {
        this.seq1 = s1;
        this.seq2 = s2;
        this.len1 = s1.length();
        this.len2 = s2.length();
        this.scoreMatrix = new int[len2 + 1][len1 + 1];
        this.traceback = new int[len2 + 1][len1 + 1];
        this.alignmentsSeq1 = new ArrayList<>();
        this.alignmentsSeq2 = new ArrayList<>();
    }

    // 核心算法:填充DP表和回溯表
    public int computeAlignment() {
        // 初始化第一行和第一列
        scoreMatrix[0][0] = 0;
        traceback[0][0] = 0;

        // 初始化第一列:seq2为空,seq1的每个字符都对应空位
        for (int i = 1; i <= len2; i++) {
            scoreMatrix[i][0] = scoreMatrix[i-1][0] + gapPenalty;
            traceback[i][0] = 4; // 4 代表来自上方(上空格)
        }
        // 初始化第一行:seq1为空,seq2的每个字符都对应空位
        for (int j = 1; j <= len1; j++) {
            scoreMatrix[0][j] = scoreMatrix[0][j-1] + gapPenalty;
            traceback[0][j] = 2; // 2 代表来自左方(左空格)
        }

        // 动态规划,填充表格主体
        for (int i = 1; i <= len2; i++) {
            for (int j = 1; j <= len1; j++) {
                // 计算三种可能情况的得分
                int matchOrMismatch = scoreMatrix[i-1][j-1] +
                    (seq1.charAt(j-1) == seq2.charAt(i-1) ? matchScore : mismatchPenalty);
                int gapInSeq2 = scoreMatrix[i][j-1] + gapPenalty; // seq2引入空位(水平)
                int gapInSeq1 = scoreMatrix[i-1][j] + gapPenalty; // seq1引入空位(垂直)

                // 找出最大值,并设置当前得分
                int maxScore = Math.max(matchOrMismatch, Math.max(gapInSeq2, gapInSeq1));
                scoreMatrix[i][j] = maxScore;

                // 记录路径来源(可能多个)
                int trace = 0;
                if (matchOrMismatch == maxScore) trace |= 1; // 1: 来自左上
                if (gapInSeq2 == maxScore) trace |= 2;       // 2: 来自左边
                if (gapInSeq1 == maxScore) trace |= 4;       // 4: 来自上边
                traceback[i][j] = trace;
            }
        }
        // 右下角的值即为全局最优得分
        return scoreMatrix[len2][len1];
    }

    // 回溯函数,递归地找出所有最优比对
    private void backtrack(int i, int j, StringBuilder alignedSeq1, StringBuilder alignedSeq2) {
        if (i == 0 && j == 0) {
            // 到达起点,保存一条完整的比对结果
            alignmentsSeq1.add(alignedSeq1.reverse().toString());
            alignmentsSeq2.add(alignedSeq2.reverse().toString());
            // 恢复反转状态,以便其他路径使用
            alignedSeq1.reverse();
            alignedSeq2.reverse();
            return;
        }

        int trace = traceback[i][j];

        // 检查并尝试所有可能的来源方向
        if (i > 0 && j > 0 && (trace & 1) != 0) { // 来自左上
            alignedSeq1.append(seq1.charAt(j-1));
            alignedSeq2.append(seq2.charAt(i-1));
            backtrack(i-1, j-1, alignedSeq1, alignedSeq2);
            alignedSeq1.deleteCharAt(alignedSeq1.length()-1);
            alignedSeq2.deleteCharAt(alignedSeq2.length()-1);
        }
        if (j > 0 && (trace & 2) != 0) { // 来自左边
            alignedSeq1.append(seq1.charAt(j-1));
            alignedSeq2.append('_');
            backtrack(i, j-1, alignedSeq1, alignedSeq2);
            alignedSeq1.deleteCharAt(alignedSeq1.length()-1);
            alignedSeq2.deleteCharAt(alignedSeq2.length()-1);
        }
        if (i > 0 && (trace & 4) != 0) { // 来自上边
            alignedSeq1.append('_');
            alignedSeq2.append(seq2.charAt(i-1));
            backtrack(i-1, j, alignedSeq1, alignedSeq2);
            alignedSeq1.deleteCharAt(alignedSeq1.length()-1);
            alignedSeq2.deleteCharAt(alignedSeq2.length()-1);
        }
    }

    // 打印所有最优比对结果
    public void printAlignments() {
        System.out.println("全局最优比对得分: " + scoreMatrix[len2][len1]);
        System.out.println("\n所有最优比对方案:");
        for (int k = 0; k < alignmentsSeq1.size(); k++) {
            System.out.println("方案 " + (k+1) + ":");
            System.out.println("Seq1: " + alignmentsSeq1.get(k));
            System.out.println("Seq2: " + alignmentsSeq2.get(k));
            System.out.println();
        }
    }

    public static void main(String[] args) {
        // 使用示例中的序列
        String s1 = "GCCCTAGCG";
        String s2 = "GCGCAATG";

        GlobalSequenceAlignment aligner = new GlobalSequenceAlignment(s1, s2);
        int bestScore = aligner.computeAlignment();

        // 从终点开始回溯,找出所有路径
        aligner.backtrack(aligner.len2, aligner.len1, new StringBuilder(), new StringBuilder());
        aligner.printAlignments();
    }
}

运行这段代码,你会得到类似这样的输出:

全局最优比对得分: 0

所有最优比对方案:
方案 1:
Seq1: GCCCTAGCG
Seq2: GCGC_AATG

方案 2:
Seq1: GCCCTAGCG
Seq2: GCGCAA_TG

方案 3:
Seq1: GCCCTAGCG
Seq2: GCGCAAT_G

代码解读与避坑指南:

  1. 回溯矩阵的位运算:我用位标志(1,2,4)来记录多个来源,并用位或操作 |= 来合并它们。回溯时用位与操作 & 来判断。这种方式比用列表或字符串存储更高效,也更容易处理多解。
  2. 递归回溯:backtrack 函数是一个经典的深度优先搜索。它从终点 (len2, len1) 开始,根据 traceback 矩阵的指引,尝试所有可能的路径回到起点 (0,0)。每找到一条完整路径,就保存一次结果。这里要注意字符串的拼接和反转顺序。
  3. 多解处理:原始序列 GCCCTAGCG 和 GCGCAATG 比对得分为0,并且有三个最优解。这在实际分析中很常见,说明这两条序列在这些计分规则下,有多个同样合理的全局对齐方式。生物学家需要根据其他生物学知识来判断哪个更可能。
  4. 复杂度:算法的时间复杂度和空间复杂度都是 O(m*n),其中m和n是序列长度。对于较长的基因组序列(如几万个碱基),这个开销是巨大的,这也是为什么Needleman-Wunsch通常用于较短的序列或核心基因比对,而对于全基因组比对需要更高效的启发式算法(如BLAST的种子延伸策略)。

4. 实战调参:计分策略如何影响你的生物学结论?

把算法跑通只是第一步。在真实的生物信息学项目中,如何设置匹配得分、错配罚分和空位罚分,直接决定了比对结果的生物学意义。这绝不是随便填几个数字那么简单。

4.1 理解计分矩阵的生物学内涵

最简单的计分矩阵就像我们代码里用的:匹配+1,错配-1,空位-2。但这太粗糙了。在分子进化中,不同的碱基替换发生的概率是不同的。例如,在DNA中,嘌呤(A,G)之间或嘧啶(C,T)之间的转换(Transition),比嘌呤和嘧啶之间的颠换(Transversion)更常见。因此,一个更合理的计分矩阵会给转换赋予比颠换更轻的惩罚(比如转换-1,颠换-2)。

更专业的方法是使用像BLOSUM或PAM这样的氨基酸替换矩阵(对于蛋白质序列比对)。这些矩阵是基于大量已知的同源蛋白家族统计得出的,其中的分数反映了氨基酸之间相互替换的进化可能性。分值越高,表示替换越容易被接受。直接使用这些成熟的矩阵,比我们自己拍脑袋定分数要科学得多。

4.2 空位罚分:线性与仿射模型

我们代码中使用的是线性空位罚分(Linear Gap Penalty):每打开一个空位或延伸一个空位,都罚固定的分数(如-2)。这在生物学上不太合理,因为一个长的插入或缺失事件(比如一段DNA的丢失)在进化上可能是一个单一事件,而不是多个独立事件的叠加。

因此,更常用的模型是仿射空位罚分(Affine Gap Penalty)。它把空位罚分分成两部分:

  • 空位开启罚分(Gap Open Penalty):第一次引入空位时的较大惩罚。
  • 空位延伸罚分(Gap Extension Penalty):空位每延长一个位置时的较小惩罚。

例如,设置开启罚分为-5,延伸罚分为-1。那么一个长度为3的空位总罚分就是 (-5) + (-1) + (-1) = -7,这比线性罚分下的 -23 = -6 惩罚更重,但比三个独立的单空位罚分 (-53=-15) 要轻。这更符合生物学上“长缺失比多个短缺失更可能发生一次”的直觉。实现仿射空位罚分需要更复杂的动态规划状态设计(通常需要三个矩阵),但思路是相通的。

4.3 一个调参实例:感受分数的力量

让我们用之前的序列 S1=GCCCTAGCG, S2=GCGCAATG 做个小实验。

参数组合 (匹配,错配,空位)最优得分可能的最优比对示例生物学解读倾向
(1, -1, -2)0GCCCTAGCG
GCGC_AATG
默认设置。平衡匹配、错配和空位。结果倾向于在中间插入一个空位来获得更多匹配。
(1, -3, -2)-4GCCCTAGCG
GCGCAATG_
加重错配惩罚。算法更不愿意接受错配,因此宁愿在末尾引入空位,也不愿让开头的‘C’和‘G’错配。这可能导致比对在末端“翘起”。
(1, -1, -5)-5GCCCTAGCG
GCGCAATG
加重空位惩罚。算法非常不愿意引入空位,因此选择直接进行字符对字符的比对,即使这导致多处错配。这适合比对高度保守、很少发生插入缺失的区域。
(2, -1, -2)3GCCCTAGCG
GCGC_AATG
提高匹配奖励。匹配的吸引力变大,算法会更积极地寻找匹配,比对结果可能与默认相似,但得分更高,信心更足。

从这个简单的实验你可以看到,参数就是你的“指挥棒”。你需要根据具体的生物学问题来调整:如果你在比对两个亲缘关系很近的物种,你可能使用高的匹配分和重的空位罚分,因为你觉得它们序列应该很相似,插入缺失应该少。如果你在比对一个基因和它可能的远亲,你可能会降低错配罚分,并使用仿射空位模型,以容忍更多的分歧。

5. 从结果到洞见:如何解读你的比对输出?

拿到比对结果文件(通常是一个包含对齐序列的文本文件,如FASTA或SAM格式)后,我们该如何从中提取有用的生物学信息呢?

5.1 识别保守区域与变异位点

比对结果最直观的用途就是可视化。将两条序列上下排列,匹配的字符通常用竖线 | 标出,错配的字符会直接显示,空位用短横线 - 表示。一眼望去,那些竖线密集的区域就是保守区域,这些区域可能在功能上非常重要(如酶的活性中心)。而那些出现错配或空位的位点,就是变异位点。你可以统计这些变异的数量和类型(转换、颠换、插入、缺失),作为进化分析的输入。

5.2 计算序列相似性与同源性推断

基于比对结果,可以计算两条序列的相似度(Similarity) 和同一性(Identity)。

  • 同一性:完全匹配的碱基数量 / 比对后的总长度(包括空位)。这是一个非常严格的指标。
  • 相似性:在考虑替换矩阵(比如BLOSUM62)后,比对的总得分,或者按某种规则(如嘌呤/嘧啶视为相似)计算的“相似”位点比例。

注意:高相似性/同一性可以提示同源性(共同的进化起源),但不能证明。 还需要结合其他证据,如基因结构、上下游序列等。但Needleman-Wunsch提供的全局最优比对,是进行这种定量计算的基础。

5.3 作为下游分析的输入

一个准确的全局比对结果是许多高级分析的前置步骤:

  • 系统发育树构建:将多条同源基因的比对结果(称为多重序列比对)作为输入,可以推断物种或基因之间的进化关系。
  • 基因注释:将一个新测序的基因与已知功能的基因数据库进行全局比对,可以推测其可能的功能。
  • 引物设计:在设计PCR引物时,需要在目标物种的DNA序列中寻找高度保守的区域,全局比对可以帮助锁定这些区域。

5.4 结果的局限性

最后必须清醒认识到Needleman-Wunsch的局限性。它是全局比对,要求序列整体相似。如果两条序列只在局部相似(比如一个结构域),而其他部分差异巨大,强行进行全局比对会把不相关的区域硬凑在一起,得到毫无生物学意义的结果,得分也会很低。这时候你就需要局部序列比对算法,比如Smith-Waterman算法。它的核心思想与Needleman-Wunsch类似,但允许比对从任何地方开始、任何地方结束,只比对相似度最高的那个片段,非常适合在长序列中寻找保守的模体或结构域。

在实际的生物信息学流程中,我们往往会根据需求选择合适的工具。Needleman-Wunsch是理解序列比对的基石,掌握了它,你就能更深入地理解BLAST等复杂工具背后的原理,也能在需要精确全局比对时,自己动手编写或调整脚本,让分析更贴合你的具体课题。

Smith-Waterman算法、Needleman-Wunsch算法的算法原理及算法比较 史密斯-沃特曼算法(Smith-Waterman algorithm)是一种进行局部序列比对(相对于全局比对)的算法,该算法的目的不是进行全序列的比对,而是找出两个序列中具有高相似度的片段。 尼德曼-翁施算法(Needleman-Wunsch Algorithm)是基于生物信息学的知识来匹配蛋白序列或者DNA序列的算法。这是将动态算法应用于生物序列的比较的最早期的几个实例之一。该算法是由 Saul... 阅读详情

相关推荐

序列比对(一)——全局比对Needleman-Wunsch算法

原创:hxj7 前言 序列比对是生信领域的一个古老课题,在这一波NGS的浪潮中重新引起大家的广泛关注。由于生物序列的特殊性,在比对的时候允许插入缺失,所以往往是一种不精确匹配。从本文开始,我们陆续学习前人开发出的流行算法。 全局比对算法 所谓全局比对算法,就是根据一个打分矩阵(替换矩阵)计算出两个序列比对最高得分的算法。关于它的介绍网上已经非常多了,我们只需看看其中的关键点及实现代码。 关键点 1...

生信了 2万+

动态编程之序列比对:Needleman-Wunsch 算法和Smith-Waterman算法

动态编程之序列比对:Needleman-Wunsch 算法和Smith-Waterman算法       在比对两个序列时,不仅要考虑完全匹配的字符,还要考虑一个序列中的空格或间隙(或者,相反地,要考虑另一个序列中的插入部分)和不匹配,在序列比对中,需要找到最优的比对(最

HUGEHEADHUGE的专栏 3万+

【基因序列比对】Needleman-Wunsch算法

前言 最近加入了一个研究基因大数据的项目组,要学习基因相关知识QAQ,所以开始一个新系列梳理知识和激励自己学习。 本系列参考了https://zhuanlan.zhihu.com/p/54142276 Needleman-Wunsch算法 Needleman-Wunsch算法是基于动态规划的算法,记不清楚的可以看下我之前的动态规划的文章,简单总结就是将一个问题分解为很多相互联系并且逐渐扩大的小问题,依次解决使问题规模逐渐扩大,最终获得问题的解。 DNA有三种情况可能导致两个序列不同: SNP单核酸多态性,

mountains_L的博客 8007

Needleman-Wunsch 算法和Smith-Waterman算法

全局和局部序列比对:       全局序列比对  尝试找到两个完整的序列 S1 和 S2 之间的最佳比对。如S1=GCCCTAGCG S2=GCGCAATG 如果设定每个匹配字符为1分,每个空格为-2分,每个不匹配为-1分,则下面的比对就是全局最优比对:S1'=GCCCTAGCG S2'=GCGC_AATG,连字符“_”代表空格。在 S2' 中有五个匹配字符,一个空格(或者反过来说,在 S1'

aldenphy的专栏 3万+

【匹配】Needleman–Wunsch

Needleman-Wunsch算法是一种用于生物序列全局比对的经典动态规划方法,由Saul B. Needleman和Christian D. Wunsch于1970年提出。该算法通过构建积分得分矩阵,利用动态规划递推计算最优比对得分,并通过回溯还原最佳全局比对路径。

wwl412095144的博客 1310

【序列比对】Needleman-Wunsch(全局)和Smith-Waterman(局部)算法py实现(多条回溯路径,三叉树思路,超详细注释)

超详细注释,py实现Needleman-Wunch和Smith-Waterman算法,多条回溯路径

池塘春草梦的博客 3184

Needleman-Wunsch(NW)算法

Needleman-Wunsch(NW)算法是一种用于生物信息学中的序列比对算法,特别是用于蛋白质和核酸序列的全局比对。这个算法由Saul B. Needleman和Christian D. Wunsch在1970年提出,其目的是找到两个序列之间最长的公共子序列,即使在序列的两端也可以存在不匹配的情况。

weixin_43156294的博客 1835

Needleman-Wunsch全局序列比对算法

Needleman-Wunsch全局序列比对算法

qq_51287641的博客 4357

【R语言双序列比对】全局比对Needleman-Wunsch算法&局部比对Smith-Waterman算法原理及代码实现

全局比对和局部比对的显著区别是局部比对的得分矩阵中的分值均≥0,即在考虑打分方式时,局部比对要多考虑一种。在初始化得分矩阵的第一行和第一列时,两者有不同。对于全局比对,需要依次加上gap罚分值,而对于局部比对,则只需要都初始化为0。全局比对和局部比对的核心思想是依次寻求重复子问题的最优子结构,通过序列比对,可以发现序列之间的相似性,也可以判别序列之间的同源性,推断序列之间的进化关系,辨别序列之间的差别,寻找遗传变异。

qq_65680034的博客 3861

序列比对之Needleman-wunsch算法的python实现

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。 新的改变 我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdow

Faker_Skt_K1的博客 2669

文本比较算法--Needleman/Wunsch算法

一、定义:定义: LCS(A,B)表示字符串A和字符串B的最长公共子串的长度。很显然,LSC(A,B)=0 表示两个字符串没有公共部分。字符串A=kitten,字符串B=sitting ,那他们的最长公共子串为ittn . (注:最长公共子串不需要连续出现,但一定是出现的顺序一致),最长公共子串长度为4。二、公式:为了讲解计算LCS(A,B),特给予以下几个定义:      A=a1

Benson的学习笔记 2万+

python 比对匹配_用Python从头实现Needleman-Wunsch序列比对算法

本文将介绍生物信息学中一个基本的序列比对算法,Needleman-Wunsch比对算法(以下简称NW算法),并展示如何编写一个简单的Python程序来实现该算法。全文分为上下两个部分:上篇介绍并阐释NW算法的原理,下篇展示如何用Python实现。如果你对该算法不陌生并且仅对实现方法感兴趣,那么可以直接跳到下篇。——————————————————— 上篇 ————————————————————序...

weixin_39725365的博客 1502

序列比对(二)——Needleman-Wunsch算法之仿射罚分

原创: hxj7 关于全局比对Needleman-Wunsch算法的介绍及线性罚分的实现代码请参考序列比对(一)全局比对Needleman-Wunsch算法。 概念引用如下: 线性罚分,即penalty=g*d,其中g为空位长度,d为一个空位的罚分。 仿射型罚分,即penalty=d+(g-1)*e, 其中g为连续空位的长度,d为连续空位中第一个空位的罚分,e为连续空位中第2个及以后空位的罚分。...

生信了 5812

(六)R语言生物序列比对——Needleman-Wunsch全局比对算法

目录实现原理与代码全部代码结束语 实现原理与代码 生物序列全局比对的主要目的是发现两个序列之间的相似度,从而估测二者的进化联系或相似功能。Needleman-Wunsch全局比对算法用到了动态规划(Dynamic Programming)的原理。它的主要工作流程见下图: 在介绍具体算法前,我们先要定义一个得分矩阵。得分矩阵的目的是告诉程序某两个碱基配对的得分: match <- 2 mismatch <- -1 gap <- -2 scoreMat <- matrix(misMa

EricFrenzy的博客 5133

Needleman-Wunsch算法

Needleman-Wunsch 算法通过动态规划计算出两个序列的全局最佳对齐方案,能够有效处理序列长度不一致或局部差异的情况,是生物序列比对的经典算法之一。

1187

74HC165级联踩坑实录:STM32读取32路开关状态,时序调试与常见问题排查

本文详细介绍了74HC165级联在STM32读取32路开关状态时的时序调试与常见问题排查。从硬件设计的PCB布局优化、电源噪声控制,到软件时序的精确调校和数据采集策略,提供了完整的解决方案。通过逻辑分析仪和示波器的高效使用,解决了信号延迟和干扰问题,最终实现了稳定可靠的32路信号读取。

weixin_34046298的博客 315

第二章 序列比对——Needleman-Wunsch全局比对

【生信】第二章 序列比对——Needleman-Wunsch全局比对 主要为基因组测序比对相关知识,部分内容作笔记自查使用。如有错误或遗漏还请海涵,可评论或邮箱联系。最后修改时间:2020-04-03 07:53:55 星期五 Needleman-Wunsch全局比对 一、符号约定 符号 说明 xandy 两个序列 M\left( {i,j} \right) 在{x_i}比对到{y_i}情况下,序列x和y目前

wangprince2017 2266

#Linux内存管理# 用一个案例详细介绍ARMv7-A架构 缺页中断处理的原理

跳转到异常向量:根据 异常向量表基地址(通常配置在 VBAR 寄存器中,例如 0xFFFF0000) + 数据中止异常的偏移量 0x10,跳转到数据中止异常的处理程序入口点 0xFFFF0010(实践中,这个入口通常是一条跳转到更复杂处理函数的指令)。malloc 通常不会立即分配物理内存页,它只是在内核为该进程维护的虚拟地址空间中找到一段足够大的空闲虚拟地址区域(比如 0x00008000 - 0x00008FFF),标记为已用,并返回起始地址(例如 0x00008000)给程序。

sinat_37817094的博客 993

Needleman/Wunsch算法

本文介绍基于最长公共子串的文本比较算法——Needleman/Wunsch算法。   还是以实例说明:字符串A=kitten,字符串B=sitting   那他们的最长公共子串为ittn(注:最长公共子串不需要连续出现,但一定是出现的顺序一致),最长公共子串长度为4。      定义:   LCS(A,B)表示字符串A和字符串B的最长公共子串的长度。很显然,LSC(A,B)=0表示两个字

叶小生的博客 4197

为何LPDDR4支持on-die ECC,但是DDR4却不支持呢?

DRAM的ECC,目前的编码方式都是128bit data,产生8bit parity或者ECC code. 而且必须要128bit才行。这8bit的ECC code是要被写入到DRAM内存里面的,从而read的时候,可以读取这8bit ECC code来判定read data是否有错,如果是SBF,就可以纠错了,如果是double bit,大部分时候是可以detect到错误,即所谓的SEC(Single Error Correct) + DED(Double Error Detect).

一个DRAM从业者的告白 1557

PCL 改进的RANSAC算法实现点云粗配准【2024最新版】

一种改进的RANSAC点云粗配准算法,具体改进见论文:“Pose Estimation using Local Structure-Specific Shape and Appearance Context”

点云侠的博客 37万+

实现序列全局对比(Needleman-Wunsch )(perl)

这篇博客我写了简单和中等难度两个比对方法 1.简单的动态规划,得出基因的最短编辑距离 简介在注释中,代码如下: #!/usr/bin/perl -w use strict; use autodie; #这个程序就是一个简单的动态规划,它只能算出最短的编辑距离,理论上与Needleman-Wunsch 算法相似 #不同的是,这个dp矩阵存的是最短编辑距离,而Needleman-Wunsch 算法的dp矩阵存的是得分情况 #这题的思想是,dp矩阵第一行与第一列都是代表某一条序列对上一条空序列,所以距离逐渐加一

qq_45091883的博客 2468

《PCI Express体系结构导读1》-- PCI简介

请先阅读完一遍此书再来看文章哦,这样效率更高~

HoneyIC的博客 153
上一篇: 机器学习超参数优化实战:GridSearchCV与交叉验证的黄金组合
下一篇: 解决Maven项目中Kabeja依赖引入问题的两种实用方法
study
博客等级 码龄27年 67粉丝 1642原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值