C#Needleman-Wunsch算法w/InDel扩展调试

C#Needleman-Wunsch算法w/InDel扩展调试,c#,dynamic-programming,dna-sequence,C#,Dynamic Programming,Dna Sequence,我需要一些帮助来发现我的Needleman Wunsch算法实现中的缺陷。现在,我一次只关注一个问题,而我面临的问题是,当计算我的最佳对齐分数时,它是关闭的,我似乎无法找出原因。我已经一遍又一遍地重复逻辑,用笔和纸做了,我不知道我做错了什么。我四处搜索,找不到任何人在计算他们与InDel扩展的对齐时有问题(这是我的问题)。我已经考虑过我的测试数据被破坏的可能性,但我不认为是这样。我的实现使用+3/-3的匹配/不匹配、-8的InDel和-1的InDel扩展。我试图在编写代码时完整地记录代码,以便理

我需要一些帮助来发现我的Needleman Wunsch算法实现中的缺陷。现在,我一次只关注一个问题,而我面临的问题是,当计算我的最佳对齐分数时,它是关闭的,我似乎无法找出原因。我已经一遍又一遍地重复逻辑,用笔和纸做了,我不知道我做错了什么。我四处搜索,找不到任何人在计算他们与InDel扩展的对齐时有问题(这是我的问题)。我已经考虑过我的测试数据被破坏的可能性,但我不认为是这样。我的实现使用+3/-3的匹配/不匹配、-8的InDel和-1的InDel扩展。我试图在编写代码时完整地记录代码,以便理解我的思路。如果有人能帮助我,我将不胜感激。目前,我得到了-1,而我应该得到-3(假设我的测试数据是正确的,因为它是专门为调试提供的)

对不起大家,我忘了提到,我调试的方法是用维基百科NWA页面上的值替换我的评分值。我能够用我的代码重现它们的特性。

using System;
using System.IO;

namespace Program
{
    class Driver
    {
        static int Main(string[] args)
        {
            //Implementation of Needleman-Wunsch algorithm, Match +3, Mismatch -3, InDel -8, InDel Extension -1

            /*using (StreamReader reader = File.OpenText(args[0]))
            while (!reader.EndOfStream)
            {
                string line = reader.ReadLine();
                if (null == line)
                    continue;
                //split line by Pipe |*/

                string line = "GCATGCT | GATTACA"; //Answer should be -3
                //string line = "GAAAAAAT | GAAT"; //Answer should be 1

                //Split our 2 sequences by pipe
                string[] arg = line.Split('|');

                //Strip all white space from both sequences and assign our sequences to A and B
                string A = arg[1].Trim();
                string B = arg[0].Trim();

                // We add +1 to the length of our strings to allow for the gap in the Needleman-Wunsch matrix
                Cell[,] scoringMatrix = new Cell[A.Length + 1, B.Length + 1];

                // We begin initiliazation of our N-W matrix starting from 0,0
                int i = 0, j = 0;
                while (i < scoringMatrix.GetLength(0))
                {
                    while (j < scoringMatrix.GetLength(1))
                    {
                        if (i == 0 && j == 0)       // This is our origin (0,0)
                            scoringMatrix[i, j] = new Cell();
                        else if (i == 0)            // First row which is simply j * gap
                            scoringMatrix[i, j] = new Cell(i, j, null, scoringMatrix[i, j - 1], null, A, B);
                        else if (j == 0)            // First column which is i * gap
                            scoringMatrix[i, j] = new Cell(i, j, scoringMatrix[i - 1, j], null, null, A, B);
                        else
                            scoringMatrix[i, j] = new Cell(i, j, scoringMatrix[i - 1, j], scoringMatrix[i, j - 1], scoringMatrix[i - 1, j - 1], A, B);
                        j++;
                    }
                    j = 0;
                    i++;
                }

                // Now we look at our scoringMatrix for the last cell of our last column and begin traceback
                Console.WriteLine(scoringMatrix[A.Length, B.Length].C());
            //}
            return 0;
        }
    }

    // This class represents each individual cell within the N-W matrix
    class Cell
    {
        private int score;
        private int row;
        private int col;
        char charA;
        char charB;
        private bool isGap;
        private Source source;

        public Cell()
        {
            // Default constructor for our matrix origin (0,0)
            score = 0;
            col = 0;
            row = 0;
            isGap = false;
            source = Source.origin;
            charA = '-';
            charB = '-';
        }
        public Cell(int r, int c, Cell t, Cell l, Cell d, string A, string B)
        {
            if (r == 0)
            {
                // Special logic for our first row, D is our gap value which is either -8 for InDel OR -1 for InDel Extension
                // We do not consider this row as gaps because they are givens

                int D = c == 1 ? -8 : -1;
                row = r;
                col = c;
                score = l.score + D;
                isGap = false;
                source = Source.left;
                charA = '-';
                charB = B[c - 1];
            }
            else if (c == 0)
            {
                // Special logic for our first column, D is our gap value which is either -8 for InDel OR -1 for InDel Extension
                // As above, we do not consider this column as gaps because they are givens

                int D = r == 1 ? -8 : -1;
                row = r;
                col = c;
                score = t.score + D;
                isGap = false;
                source = Source.top;
                charA = A[r - 1];
                charB = '-';
            }
            else
            {
                // To determine our gap costs we look to our left and see if this is an extension or a new instance of gap
                int D = l.isGap ? -1 : -8;

                // We determine our top sum score using the cell above us score C() plus our predetermined gap value D
                int top = t.C() + D;

                // We determine our left sum score using the cell left of us score C() plus our predetermined gap value D
                int left = l.C() + D;

                // For debugging purposes we are saving which characters we are comparing
                charA = A[r - 1];
                charB = B[c - 1];

                // We determine our diagonal sum score using the left diagonal of us score C() plus our match/mismatch value from S(A[i],B[j])
                int diag = d.C() + S(charA, charB);

                row = r;
                col = c;

                // The right decision is made by choosing the max of the 3 computed scores top, left, and diag
                score = Math.Max(top, Math.Max(left, diag));

                // We determine this cell to be a gap IF top or left is chosen (i.e. top OR left > diag)
                isGap = determineGap(top, left, diag);

                // We assign our source based on which of these three was chosen
                source = findSource(top, left, diag);
            }
        }
        public int S(char A, char B)
        {
            // We determine our match/mismatch value by checking if these 2 characters match, this value is either +3 or -3
            return (A == B) ? 3 : -3;
        }
        public int C()
        {
            // Return our score
            return score;
        }
        private bool determineGap(int top, int left, int diag)
        {
            // If the diagonal cell is greater than both left and top then we are definitely NOT going to have a gap
            if (diag > top && diag > left)
                return false;
            else
                return true;
        }
        private Source findSource(int top, int left, int diag)
        {
            // Here we need to determine where did we get our score from, we cover all the possible permutations
            if (diag > top && diag > left)
                return Source.diag;
            else if (top > diag && top > left)
                return Source.top;
            else if (left > diag && left > top)
                return Source.left;
            else if (left == diag || top == diag)
                return Source.diag;
            else
                return Source.origin;
        }
        public enum Source
        {
            // Which cell did our score come from
            origin,
            left,
            top,
            diag
        }
        public bool isOrigin()
        {
            // Is this our origin cell
            return source == Source.origin ? true : false;
        }
        public string mySource()
        {
            // Convert the enum to a string
            return source.ToString();
        }
    }
}
使用系统;
使用System.IO;
名称空间程序
{
类驱动程序
{
静态int Main(字符串[]args)
{
//Needleman-Wunsch算法的实现,匹配+3,匹配-3,InDel-8,InDel扩展-1
/*使用(StreamReader=File.OpenText(args[0]))
而(!reader.EndOfStream)
{
字符串行=reader.ReadLine();
if(null==行)
继续;
//逐管分流|*/
string line=“GCATGCT | GATTACA”//答案应该是-3
//string line=“gaaaaat | GAAT”//答案应该是1
//用管道将我们的两个序列分开
字符串[]arg=line.Split(“|”);
//从两个序列中去除所有空白,并将我们的序列分配给A和B
字符串A=arg[1]。Trim();
字符串B=arg[0]。Trim();
//我们将字符串的长度加上+1,以允许Needleman Wunsch矩阵中的间隙
单元格[,]烧焦矩阵=新单元格[A.长度+1,B.长度+1];
//我们从0,0开始初始化N-W矩阵
int i=0,j=0;
而(i