当前位置: 首页 > news >正文

Smith-Waterman 算法(C++实现)

本文实现Smith-Waterman 算法案例,用于局部序列比对。该算法是生物信息学中用于寻找两个 DNA、RNA 或蛋白质序列之间最优局部比对的经典算法,广泛应用于序列相似性分析和功能预测。


问题描述

给定两个生物序列 seq1seq2,如何找到它们的最优局部比对,使得比对得分最大化?


算法思想

Smith-Waterman 算法的核心思想是动态规划,通过构建一个得分矩阵,逐步计算两个序列的比对得分,并回溯找到最优局部比对路径。与 Needleman-Wunsch 算法不同,Smith-Waterman 算法允许比对从任意位置开始和结束,更适合寻找局部相似性。具体步骤如下:

  1. 初始化得分矩阵,其中 dp[i][j] 表示 seq1 的前 i 个字符与 seq2 的前 j 个字符的比对得分。
  2. 填充得分矩阵,考虑四种可能的比对操作:
    • 匹配或错配:dp[i-1][j-1] + score(seq1[i], seq2[j])
    • 插入空格:dp[i][j-1] + gap_penalty
    • 删除空格:dp[i-1][j] + gap_penalty
    • 比对从当前位置重新开始:0
  3. 回溯得分矩阵,找到最优局部比对路径。

C++代码实现

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

// 定义得分函数
int match_score(char a, char b) {
    return (a == b) ? 1 : -1; // 匹配得分为 1,错配得分为 -1
}

// Smith-Waterman 算法
pair<int, string> smithWaterman(const string& seq1, const string& seq2, int gap_penalty = -1) {
    int m = seq1.size();
    int n = seq2.size();

    // 初始化得分矩阵
    vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
    int max_score = 0; // 记录最大得分
    int max_i = 0, max_j = 0; // 记录最大得分的位置

    // 填充得分矩阵
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            int match = dp[i - 1][j - 1] + match_score(seq1[i - 1], seq2[j - 1]);
            int insert = dp[i][j - 1] + gap_penalty;
            int del = dp[i - 1][j] + gap_penalty;
            dp[i][j] = max({0, match, insert, del});

            // 更新最大得分及其位置
            if (dp[i][j] > max_score) {
                max_score = dp[i][j];
                max_i = i;
                max_j = j;
            }
        }
    }

    // 回溯找到最优局部比对
    string align1, align2;
    int i = max_i, j = max_j;
    while (i > 0 && j > 0 && dp[i][j] != 0) {
        if (dp[i][j] == dp[i - 1][j - 1] + match_score(seq1[i - 1], seq2[j - 1])) {
            align1 = seq1[i - 1] + align1;
            align2 = seq2[j - 1] + align2;
            i--;
            j--;
        } else if (dp[i][j] == dp[i][j - 1] + gap_penalty) {
            align1 = '-' + align1;
            align2 = seq2[j - 1] + align2;
            j--;
        } else {
            align1 = seq1[i - 1] + align1;
            align2 = '-' + align2;
            i--;
        }
    }

    return {max_score, align1 + "\n" + align2};
}

int main() {
    string seq1 = "GATTACA";
    string seq2 = "GCATGCU";

    auto result = smithWaterman(seq1, seq2);
    cout << "最优局部比对得分: " << result.first << endl;
    cout << "最优局部比对结果: " << endl << result.second << endl;

    return 0;
}

关键解析

  1. 时间复杂度O(m * n),其中 mn 分别是两个序列的长度。
  2. 空间复杂度O(m * n),用于存储得分矩阵。
  3. 适用场景
    • 局部序列比对。
    • 寻找序列中的功能域或保守区域。

输出示例

最优局部比对得分: 2
最优局部比对结果: 
AT
AT

总结

Smith-Waterman 算法是生物信息学中用于局部序列比对的经典算法,通过动态规划和回溯找到最优局部比对。

http://www.dtcms.com/a/122384.html

相关文章:

  • SpringBoot 接口限流Lua脚本接合Redis 服务熔断 自定义注解 接口保护
  • postman 安装及使用 [软件测试工具]
  • 如何根据不同文字内容批量生产手写的图片,模拟真人写的笔记(待验证)
  • 代码随想录算法训练营Day24
  • 第1章 对大型语言模型的介绍
  • SQL优化技术分享:从 321 秒到 0.2 秒的性能飞跃 —— 基于 PawSQL 的 TPCH 查询优化实战
  • 栈与队列及其基础应用
  • 【Kafka基础】topic命令行工具kafka-topics.sh:基础操作命令解析
  • STM32低功耗
  • 数据结构--堆
  • 软件测试之功能测试详解
  • C++语法学习之路
  • Mac监控新风尚:酷炫界面,性能监控更直观!
  • 数字图像处理作业4
  • SQLite 中日期型数据定义及处理(Delphi 版本)
  • IDEA :物联网ThingsBoard-gateway配置,运行Python版本,连接thingsboard,接入 MQTT 设备
  • [ACM_1] 输入输出 | 多行 | 多组 | getline(cin,s) | cin处理
  • 【MySQL】——事务的隔离性
  • Dubbo的简单介绍
  • 数据分析-Excel-学习笔记Day1
  • LeetCode Hot100 刷题笔记(2)—— 子串、普通数组、矩阵
  • Ubuntu22.04——YOLOv8模型训练到RK3588设备部署和推理
  • 实现抗隐私泄漏的AI人工智能推理
  • Linux进程控制:fork、exit与waitpid的江湖恩怨
  • C# 根据指定路径、文件格式、创建日期清理文件夹内文件,包括子目录
  • 从Transformer到世界模型:AGI核心架构演进
  • 微信小程序 -- 原生封装table
  • UV安装与使用
  • asp.net core 项目发布到 IIS 服务器
  • 场外期权只适合上涨行情吗?