生物信息学(2)——双序列比对之Smith-Waterman(SW)算法详解

生物信息学系列博客索引

生物信息学(1)——双序列比对之Needleman-Wunsch(NW)算法详解及C++实现
生物信息学(2)——双序列比对之Smith-Waterman(SW)算法详解
生物信息学(3)——双序列比对之BLAST算法简介
生物信息学(4)——多序列比对之CLUSTAL算法详解及C++实现
生物信息学(5)——基于CUDA的多序列比对并行算法的设计与代码实现
项目gitee地址,内附源码、论文等文档信息

1. SW 算法简介

Smith-Waterman 算法是由 Temple F. Smith 和 Michael S. Waterman 两人在 1981 年提出来的,是 Needleman-Wunsch 算法的改良版,通过算法的比对,能获 取到局部最优解。SW 算法罚分规则如下:
SW 算法罚分规则如公式
在这里插入图片描述
以罚分规则为基础,得分矩阵的公式如下,可以看到,和上篇介绍的NW算法相比,最大的改变是,多了一个0。这样做就可以杜绝得分矩阵中的负数。
在这里插入图片描述
获取得分矩阵后,找全局最大的值,在此点往左上回溯,到0停止,然后根据回溯路径获取局部最优解。回溯规则:回溯规则如公式
在这里插入图片描述

2. SW算法举例介绍

给定序列

Seq1 = GGATCGA
Seq2 = GAATTCAGTTA
(1) 初始化打分矩阵

首先将矩阵的第0行与第0列分别用Seq1与Seq2填充,填充时,注意预留出两个字符,将第二行与第二列的元素置0,如图所示:
在这里插入图片描述

(2) 通过公式构建整个打分矩阵

在这里插入图片描述

(3) 回溯

先找到全局最大的值,在此点往左上回溯,到 0 停止
在这里插入图片描述

(4) 得出结果

通过回溯规则,构建最终的局部最优解,其中路径朝向左上,即 MATCH/DISMATCH,路径朝左为 seq1 出现 INDEL 情况,路径朝上为 seq2 出现 INDEL 情况,使用 ’-’ 代替。结果如下:最后得出如图 结果,为局部最优解。
在这里插入图片描述

3. 奇怪的内容

问:为什么SW算法没有C++实现?
答:问得好!因为我太懒了,我的毕设没有用到SW算法具体实现,所以无代码,只有原理解释。

4. 总结

SW算法相比较于NW算法,虽然S简化了计算过程,且是在NW算法的基础上进行改进,但是其不能获取到全局最优解,而是只能获取到局部最优解。

算法永远是时间、空间、准确性三者交错的结合,减少了时间复杂度也许会增加空间复杂度,减少了空间复杂度,也许会增加运行时间。缩短时空复杂度,算法的精度可能会丢失。有时候,我们能承受巨大的内存空间,无法容忍运行的速度低下,所以我们会选择时间复杂度低的算法,有时候我们想优化时空复杂度,对结果没有偏执的要求,那又是另一种选择。所以适合使用情况的算法才是好的算法。正如下一篇要介绍的BLAST,其并不确保能找到最优解,但尽力在更短时间内找到足够好的解。これは人生かもしれません

  • 10
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Smith-Waterman算法是一种用于序列比对的动态规划算法。它可以用于比对DNA、RNA、蛋白质序列等。C++是一种高效的编程语言,可以用于实现Smith-Waterman算法。 实现Smith-Waterman算法C++代码需要考虑以下几个方面: 1. 输入序列:需要从文件或者用户输入中读取待比对的序列。 2. 动态规划矩阵:需要创建一个二维数组来存储动态规划矩阵。 3. 算法实现:需要实现算法的核心部分,包括初始化矩阵、计算得分、回溯路径等。 4. 输出结果:需要将比对结果输出到文件或者屏幕上。 以下是一个简单的Smith-Waterman算法C++实现示例: ```c++ #include <iostream> #include <fstream> #include <cstring> using namespace std; const int MAXLEN = 1000; const int GAP = -2; const int MATCH = 3; const int MISMATCH = -1; int score[MAXLEN][MAXLEN]; int max(int a, int b, int c) { int m = a; if (b > m) m = b; if (c > m) m = c; return m; } void init(int n, int m) { for (int i = 0; i <= n; i++) { score[i][0] = 0; } for (int j = 0; j <= m; j++) { score[0][j] = 0; } } void compute_score(char* s1, char* s2, int n, int m) { for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { int match = score[i-1][j-1] + (s1[i-1] == s2[j-1] ? MATCH : MISMATCH); int delete_gap = score[i-1][j] + GAP; int insert_gap = score[i][j-1] + GAP; score[i][j] = max(match, delete_gap, insert_gap); } } } void traceback(char* s1, char* s2, int n, int m) { int i = n, j = m; while (i > 0 && j > 0) { int match = score[i-1][j-1] + (s1[i-1] == s2[j-1] ? MATCH : MISMATCH); int delete_gap = score[i-1][j] + GAP; int insert_gap = score[i][j-1] + GAP; if (score[i][j] == match) { cout << s1[i-1] << " " << s2[j-1] << endl; i--; j--; } else if (score[i][j] == delete_gap) { cout << s1[i-1] << " -" << endl; i--; } else { cout << "- " << s2[j-1] << endl; j--; } } } int main() { char s1[MAXLEN], s2[MAXLEN]; cin >> s1 >> s2; int n = strlen(s1), m = strlen(s2); init(n, m); compute_score(s1, s2, n, m); traceback(s1, s2, n, m); return 0; } ``` 该示例代码实现了Smith-Waterman算法的核心部分,包括初始化矩阵、计算得分、回溯路径等。在输入两个待比对的序列后,程序会输出比对结果。需要注意的是,该示例代码只是一个简单的实现,实际应用中可能需要进行更多的优化和改进。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大青儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值