我必须编写一个程序,使用仿射空位罚函数在两个序列之间进行全局比对。动态算法(修改后的Needleman Wunsch)计算两个给定序列的相似性(表达相似序列的最大分数), s 和 t 。并且它通过构建三个2d数组来考虑间隙,序列中连续空间的块,这些块更可能发生在隔离空间中。这些数组可能没有正式描述为:
数组C:保持以序列 s 与序列 t 的字符对齐结束的块的最大分数;
数组BS:保持最大值以序列 t 的字符结尾的块的分数 s
数组BT:保持以序列 s 的字符结尾的块的最大分数 t ; <
该算法具有以下递归关系:
C [i,j] = v(s [i],t [j])+ max {C [i-1] [j-1],BS [i-1] [j-1],BT [I-1] [j-1]}
BS [i,j] = max {C [i] [j-1] - (h + g),BS [i] [j-1] -g,BT [i] [j-1] - (h +克)}
BT [i,j] = max {C [i-1] [j] - (h + g),BS [i-1] [j] - (h + g),BT [i-1] [j] -g}
** v(s [i],t [i])=匹配的值(当两个字符相同时)或不匹配(当字符不相同时)
相似性是每个数组的最后一个值中的最高值。 问题是当我运行程序时,它有一个奇怪的行为:
对于给定的一对序列,如果我改变哪一个是t或s,我的程序为同一对序列给出不同的值。那么,请你帮我找出程序有这种行为的原因吗?你知道我做错了什么吗?关于代码,这里有:
int main (void){
int mat, mis, h, g,
sim, i, j, m, n;
/* mat = match, mis = mismatch, h = open gap penalty, g = extend gap penalty */
string s, t;
s = malloc(1500);
t = malloc(1500);
scanf("%d %d %d %d", &mat, &mis, &h, &g);
scanf("%s", s);
scanf("%s", t);
m = strlen(s);
n = strlen(t);
int C[m][n], BS[m][n], BT[m][n];
C[0][0] = 0;
for(j = 1; j<= n; j++)
C[0][j] = -32000;
for(i = 1; i<= m; i++)
C[i][0] = -32000;
for(j = 1; j <= n; j++)
BS[0][j] = -(h + g*j);
for(i = 0; i <= m; i++)
BS[i][0] = -32000;
for(j = 0; j <= n; j++)
BT[0][j] = -32000;
for(i = 1; i <= m; i++)
BT[i][0] = -(h + g*i);
for(i = 1; i <= m; i++){
for(j = 1; j <= n; j++){
C[i][j] = align(s[i-1],t[j-1],mat,mis) + max(C[i-1][j-1],BS[i-1][j-1],BT[i-1][j-1]);
BS[i][j] = max((C[i][j-1]-(h+g)),(BS[i][j-1]-g),(BT[i][j-1])-(h+g));
BT[i][j] = max((C[i-1][j]-(h+g)),(BS[i-1][j]-(h+g)),(BT[i-1][j]-g));
}
}
printf("\n");
printf("c[m][n]: %d bs[m][n]:%d bt[m][n]: %d\n", C[m][n], BS[m][n], BT[m][n]);
sim = max(C[m][n], BS[m][n], BT[m][n]);
printf("sim: %d\n", sim);
return 0;
}
答案 0 :(得分:2)
好的,我在尝试了很多printfs之后终于找到了问题,因为我不知道如何使用调试器。
我的第一个线索是gcc在我尝试阅读时告诉我的分段错误来自文件的序列(具有相对大的长度)。确实,分段错误可能有多种原因,但几乎所有的时间我都在程序中看到这个错误,因为我试图访问一个实际上不存在于数组中的位置。
然后,许多printfs在初始化步骤中显示了一些值,这些值与每个数组的第一行和第一列应该具有的值不同。我将分段错误与初始化步骤中的奇怪值相关联,并决定检查数组的声明步骤以及所有循环条件。那是它!我忘记了任何数组的一个非常基本的功能:如果数组的大小 n ,您可以从零访问 n-1 。
为了解决我的新手错误,我在每个数组中为行和列添加了一个位置(因为位置(0,0)与任何对齐的字符对没有关联),因此每个数组的大小都为 [m] [n] ,其中 m 是序列 s 的(长度+ 1), n 是(长度+ 1)序列 t 。此外,我改变了所有循环条件,直到 [m-1] [n-1] 位置。现在程序运行正常。