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

时间:2016-09-15 02:02:44

标签: c# dynamic-programming dna-sequence

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

对不起大家,我忘了提及,我调试的方式是用维基百科的NWA页面中的值替换我的得分值。我能够使用我的代码重现他们的matrix

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();
        }
    }
}

0 个答案:

没有答案