Neddle-Wunch算法的C++实现

本文深入探讨了NW算法与遗传算法在生物信息学领域的应用,重点介绍了NW算法的动态规划原理及其实现过程。通过具体代码示例,展示了如何使用动态规划解决生物序列比对问题,同时讨论了算法教学的难点与挑战。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

生物信息课要求每人准备一个ppt,介绍生物信息学领域的相关内容。所以我脑海中瞬间浮现了NW算法与遗传算法。正好一个是计算机技术解决生物问题,一个是生物学思想指导的算法。接下来大部分时间用来NW算法的代码了,发现写着还是有点难度的,毕竟这么久没有写代码了。NW算法的核心就是动态规划,结合设定的罚分矩阵,思路挺容易的,就是实现的时候,要记得走过的最优路径,并且最后显示出来。

  课上的讲解,效果其实并不好。因为动态规划这个思想在十分钟内能说清已经不错了,要想懂,还得自己琢磨。

并且教授这门课的老师,并不是偏向于算法设计方向的,讲了半天没人回应额.........

下面是我写的代码,基本能实现要求:

#include<iostream>
#include<string>
using namespace std;
struct Pair{
int w;
int v;//v是该位置的累计积分。 
};//w的允许有三个值,0代表向下的箭头,1代表斜向下的箭头,2代表向右的箭头。 
 int tran(char a){
 	int c;
 	if (a=='A'){
 		c=0;
	 }
 	if (a=='G'){
 		c=1;
	 }if (a=='C'){
 		c=2;
	 }if (a=='T'){
 		c=3;
	 }
 	return c;
 	
 }//将输入的字符序列变为数字序列。 
int main(){
	string s1;
	string s2;
	cin >> s1 >> s2;//限制输入 的字符串的长度小于100 
	int m,n;
	m=s1.size();
	n=s2.size();
	//将输入的字符串AGCT转化为0,1,2,3
	
	int  s[5][5];
	int  gap=-5;
	s[0][0]=10;s[1][0]=-1;s[2][0]=-3;s[2][1]=-5;
	s[1][1]=7;s[3][0]=-4;s[3][1]=-3;s[3][2]=0;
	s[2][2]=9;
	s[3][3]=8;
	for(int i=0;i<4;i++){
		for(int j=0;j<4;j++){
			if(s[i][j]!=0){
				s[j][i]=s[i][j];
			}
		}
	}
	Pair dp[100][100];
	dp[0][0].v=0;
	
	dp[0][0].w=0;
	for(int i=0;i<=m;i++){
		for(int j=0;j<=n;j++){
			if(i==0&&j!=0){
				dp[i][j].v=dp[i][j-1].v+gap; 
				dp[i][j].w=2;
			} 
			if(j==0&&i!=0){
				dp[i][j].v=dp[i-1][j].v+gap;
				dp[i][j].w=0;
			}//以上是计算基准情况  
		}
	}	
	for(int i=1;i<=m;i++){
		for(int j=1;j<=n;j++){
		int	x=tran(s1[i-1]);
			 int y=tran(s2[j-1]);
		if(dp[i-1][j].v+gap>dp[i-1][j-1].v+s[x][y]){
			dp[i][j].v=dp[i-1][j].v+gap;
			dp[i][j].w=0;
		}
		else{
			dp[i][j].v=dp[i-1][j-1].v+s[x][y];
			dp[i][j].w=1;
			
		}
		if(dp[i][j].v<dp[i][j-1].v+gap){
			dp[i][j].w=2;
			dp[i][j].v=dp[i][j-1].v+gap;
		}
		}
	}	
	
	cout << "最终得分矩阵为" << endl; 
	for(int i=0;i<=m;i++){
		for(int j=0;j<=n;j++){
			cout << dp[i][j].v << " ";
			if(j==n){
				cout << endl;
			}
			
				
		}
	} 
	 
string s3,s4;//存放排队的方案
 int a,b;
 a=m;b=n;
 int xx=0;
 
 while(a>=0&&b>=0){
 	if(dp[a][b].w==0){
 		s3[xx]=s1[a-1];
 		s4[xx]=' ';
         a-=1;	
	 }
 	else{
	 if(dp[a][b].w==1){
 		s3[xx]=s1[a-1];
 		s4[xx]=s2[b-1];
 		a-=1;
 		b-=1;
	 }
 
 else{
 	if(dp[a][b].w==2){
 		s3[xx]=' ';
 		s4[xx]=s2[b-1];
 		b-=1;
	 }
}
}
 
 	xx=xx+1;
 	
 }
cout << "输出标记的路径:" << endl;
for(int i=0;i<=m;i++){
		for(int j=0;j<=n;j++){
			cout << dp[i][j].w<< " ";
			if(j==n){
				cout << endl;
			}
			
				
		}
	} 

	cout << "输出最相似的配对方案" << endl;
	for(int i=xx-2;i>=0;i--){
		cout << s3[i];
	} 
	 cout << endl;
	 for(int i=xx-2;i>=0;i--){
	 	cout << s4[i];
	 }
	 
	 cout << endl;
	
	
	return 0;
} 

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值