예제 #1
0
        /// <summary>
        /// Funkcja znajdująca najlepsze dopasowanie podciągów.
        /// </summary>
        /// <param name="v">pierwszy ciąg wejściowy</param>
        /// <param name="w">drugi ciąg wejściowy</param>
        /// <param name="alignment">obiekt opisujący najlepsze dopasowanie podciągów.
        /// Uwaga, w wersji z podciągami ustaw:
        /// al.VStart = indeks pierwszego elementu optymalnego podciągu v, który dopasowywaliśmy
        /// al.WStart = indeks pierwszego elementu optymalnego podciągu w, który dopasowywaliśmy
        /// al.VEnd = indeks pierwszego elementu za optymalnym podciągiem v, który dopasowywaliśmy
        /// al.WEnd = indeks pierwszego elementu za optymalnym podciągiem w, który dopasowywaliśmy
        /// </param>
        /// <returns>wartość najlepszego dopasowania</returns>
        public int FindSubsequenceAlignment(string v, string w, out Alignment alignment)
        {
            alignment = new Alignment();

            int globalMax = int.MinValue;

            int[,] assessments   = new int[w.Length + 1, v.Length + 1];
            LastOp[,] operations = new LastOp[w.Length + 1, v.Length + 1];

            List <char> sbv = new List <char>();
            List <char> sbw = new List <char>();

            for (int i = 1; i < w.Length + 1; i++)
            {
                assessments[i, 0] = i * Epsilon;
                operations[i, 0]  = LastOp.GapV;
            }
            for (int i = 1; i < v.Length + 1; i++)
            {
                assessments[0, i] = i * Epsilon;
                operations[0, 1]  = LastOp.GapW;
            }

            for (int i = 1; i < w.Length + 1; i++)
            {
                for (int j = 1; j < v.Length + 1; j++)
                {
                    int cost = Matrix[w[i - 1], v[j - 1]];
                    int maxValue;
                    if (assessments[i - 1, j] + Epsilon > assessments[i, j - 1] + Epsilon)
                    {
                        if (assessments[i - 1, j - 1] + cost > assessments[i - 1, j] + Epsilon)
                        {
                            maxValue         = assessments[i - 1, j - 1] + cost;
                            operations[i, j] = LastOp.Change;
                        }
                        else
                        {
                            maxValue         = assessments[i - 1, j] + Epsilon;
                            operations[i, j] = LastOp.GapV;
                        }
                    }
                    else
                    {
                        if (assessments[i - 1, j - 1] + cost > assessments[i, j - 1] + Epsilon)
                        {
                            maxValue         = assessments[i - 1, j - 1] + cost;
                            operations[i, j] = LastOp.Change;
                        }
                        else
                        {
                            maxValue         = assessments[i, j - 1] + Epsilon;
                            operations[i, j] = LastOp.GapW;
                        }
                    }

                    if (maxValue < cost)
                    {
                        assessments[i, j] = cost;
                        operations[i, j]  = LastOp.Skip;
                        if (cost > globalMax)
                        {
                            globalMax      = cost;
                            alignment.WEnd = i;
                            alignment.VEnd = j;
                        }
                    }
                    else
                    {
                        assessments[i, j] = maxValue;
                        if (maxValue > globalMax)
                        {
                            globalMax      = maxValue;
                            alignment.WEnd = i;
                            alignment.VEnd = j;
                        }
                    }
                }
            }

            int iv = alignment.VEnd, iw = alignment.WEnd;

            bool skipDetected = false;

            for (; !skipDetected && iv > 0 && iw > 0;)
            {
                if (operations[iw, iv] == LastOp.Change)
                {
                    sbv.Add(v[iv - 1]);
                    sbw.Add(w[iw - 1]);
                    iv--; iw--;
                }
                else
                {
                    if (operations[iw, iv] == LastOp.GapV)
                    {
                        sbv.Add('-');
                        sbw.Add(w[iw - 1]);
                        iw--;
                    }
                    else
                    {
                        if (operations[iw, iv] == LastOp.GapW)
                        {
                            sbw.Add('-');
                            sbv.Add(v[iv - 1]);
                            iv--;
                        }
                        else
                        {
                            sbv.Add(v[iv - 1]);
                            sbw.Add(w[iw - 1]);
                            iv--;
                            iw--;
                            skipDetected = true;
                        }
                    }
                }
            }
            alignment.VStart = iv;
            alignment.WStart = iw;

            sbv.Reverse();
            sbw.Reverse();

            alignment.AlignedV = String.Concat(sbv.ToArray());
            alignment.AlignedW = String.Concat(sbw.ToArray());

            return(globalMax);
        }
예제 #2
0
        /// <summary>
        /// Funkcja znajdująca najlepsze dopasowanie ciągów (bez uwzględniania podciągów).
        /// </summary>
        /// <param name="v">pierwszy ciąg wejściowy</param>
        /// <param name="w">drugi ciąg wejściowy</param>
        /// <param name="alignment">obiekt opisujący najlepsze dopasowanie.
        /// Uwaga, w wersji bez uwzględniania podciągów ustaw:
        /// alignment.VStart = 0;
        /// alignment.WStart = 0;
        /// alignment.VEnd = v.Length;
        /// alignment.WEnd = w.Length;
        /// </param>
        /// <returns>wartość najlepszego dopasowania</returns>
        public int FindAlignment(string v, string w, out Alignment alignment)
        {
            alignment = new Alignment();
            int a = v.Length, b = w.Length;

            int[,] matrix    = new int[v.Length + 1, w.Length + 1];
            LastOp[,] action = new LastOp[v.Length + 1, w.Length + 1];

            for (int i = 0; i <= a; i++)
            {
                matrix[i, 0] = i * Epsilon;
                action[i, 0] = LastOp.GapW;
            }
            for (int i = 0; i <= b; i++)
            {
                matrix[0, i] = i * Epsilon;
                action[0, i] = LastOp.GapV;
            }
            for (int i = 1; i <= a; i++)
            {
                for (int j = 1; j <= b; j++)
                {
                    matrix[i, j] = Maximum(
                        matrix[i - 1, j] + Epsilon,
                        matrix[i, j - 1] + Epsilon,
                        matrix[i - 1, j - 1] + Matrix[v[i - 1], w[j - 1]],
                        out action[i, j]
                        );
                }
            }

            StringBuilder vRes = new StringBuilder();
            StringBuilder wRes = new StringBuilder();

            while (a > 0 || b > 0)
            {
                switch (action[a, b])
                {
                case LastOp.GapV:
                    vRes.Append('-');
                    wRes.Append(w[b - 1]);
                    --b;
                    break;

                case LastOp.GapW:
                    vRes.Append(v[a - 1]);
                    wRes.Append('-');
                    --a;
                    break;

                case LastOp.Change:
                    vRes.Append(v[a - 1]);
                    wRes.Append(w[b - 1]);
                    --a; --b;
                    break;
                }
            }
            var alignedV       = vRes.ToString().ToCharArray();

            Array.Reverse(alignedV);
            var alignedW = wRes.ToString().ToCharArray();

            Array.Reverse(alignedW);
            alignment.VStart   = 0;
            alignment.WStart   = 0;
            alignment.VEnd     = v.Length;
            alignment.WEnd     = w.Length;
            alignment.AlignedV = new string(alignedV);
            alignment.AlignedW = new string(alignedW);
            //-----------------------------------------
            //Console.WriteLine();
            //Console.WriteLine("Alignment with cost: {0}", matrix[v.Length, w.Length]);
            //Console.WriteLine("Word v: {0}", alignment.AlignedV);
            //Console.WriteLine("Word w: {0}", alignment.AlignedW);
            //-----------------------------------------
            return(matrix[v.Length, w.Length]);
        }
예제 #3
0
        /// <summary>
        /// Funkcja znajdująca najlepsze dopasowanie ciągów (bez uwzględniania podciągów).
        /// </summary>
        /// <param name="v">pierwszy ciąg wejściowy</param>
        /// <param name="w">drugi ciąg wejściowy</param>
        /// <param name="alignment">obiekt opisujący najlepsze dopasowanie.
        /// Uwaga, w wersji bez uwzględniania podciągów ustaw:
        /// al.VStart = 0;
        /// al.WStart = 0;
        /// al.VEnd = v.Length;
        /// al.WEnd = w.Length;
        /// </param>
        /// <returns>wartość najlepszego dopasowania</returns>
        public int FindAlignment(string v, string w, out Alignment alignment)
        {
            alignment        = new Alignment();
            alignment.VStart = 0;
            alignment.WStart = 0;
            alignment.VEnd   = v.Length;
            alignment.WEnd   = w.Length;

            int[,] assessments   = new int[w.Length + 1, v.Length + 1];
            LastOp[,] operations = new LastOp[w.Length + 1, v.Length + 1];

            List <char> sbv = new List <char>();
            List <char> sbw = new List <char>();

            operations[0, 0] = LastOp.Skip;

            for (int i = 1; i < w.Length + 1; i++)
            {
                assessments[i, 0] = i * Epsilon;
                operations[i, 0]  = LastOp.GapV;
            }
            for (int i = 1; i < v.Length + 1; i++)
            {
                assessments[0, i] = i * Epsilon;
                operations[0, 1]  = LastOp.GapW;
            }

            for (int i = 1; i < w.Length + 1; i++)
            {
                for (int j = 1; j < v.Length + 1; j++)
                {
                    int cost = Matrix[w[i - 1], v[j - 1]];
                    if (assessments[i - 1, j] + Epsilon > assessments[i, j - 1] + Epsilon)
                    {
                        if (assessments[i - 1, j - 1] + cost > assessments[i - 1, j] + Epsilon)
                        {
                            assessments[i, j] = assessments[i - 1, j - 1] + cost;
                            operations[i, j]  = LastOp.Change;
                        }
                        else
                        {
                            assessments[i, j] = assessments[i - 1, j] + Epsilon;
                            operations[i, j]  = LastOp.GapV;
                        }
                    }
                    else
                    {
                        if (assessments[i - 1, j - 1] + cost > assessments[i, j - 1] + Epsilon)
                        {
                            assessments[i, j] = assessments[i - 1, j - 1] + cost;
                            operations[i, j]  = LastOp.Change;
                        }
                        else
                        {
                            assessments[i, j] = assessments[i, j - 1] + Epsilon;
                            operations[i, j]  = LastOp.GapW;
                        }
                    }
                }
            }

            int iv = v.Length, iw = w.Length;

            for (; iw > 0 || iv > 0;)
            {
                if (operations[iw, iv] == LastOp.Change)
                {
                    sbv.Add(v[iv - 1]);
                    sbw.Add(w[iw - 1]);
                    iv--; iw--;
                }
                else
                {
                    if (operations[iw, iv] == LastOp.GapV)
                    {
                        sbv.Add('-');
                        sbw.Add(w[iw - 1]);
                        iw--;
                    }
                    else
                    {
                        sbw.Add('-');
                        sbv.Add(v[iv - 1]);
                        iv--;
                    }
                }
            }

            sbv.Reverse();
            sbw.Reverse();

            alignment.AlignedV = String.Concat(sbv.ToArray());
            alignment.AlignedW = String.Concat(sbw.ToArray());

            return(assessments[w.Length, v.Length]);
        }
예제 #4
0
        /// <summary>
        /// Funkcja znajdująca najlepsze dopasowanie podciągów.
        /// </summary>
        /// <param name="v">pierwszy ciąg wejściowy</param>
        /// <param name="w">drugi ciąg wejściowy</param>
        /// <param name="alignment">obiekt opisujący najlepsze dopasowanie podciągów.
        /// Uwaga, w wersji z podciągami ustaw:
        /// alignment.VStart = indeks pierwszego elementu optymalnego podciągu v, który dopasowywaliśmy
        /// alignment.WStart = indeks pierwszego elementu optymalnego podciągu w, który dopasowywaliśmy
        /// alignment.VEnd = indeks pierwszego elementu za optymalnym podciągiem v, który dopasowywaliśmy
        /// alignment.WEnd = indeks pierwszego elementu za optymalnym podciągiem w, który dopasowywaliśmy
        /// </param>
        /// <returns>wartość najlepszego dopasowania</returns>
        public int FindSubsequenceAlignment(string v, string w, out Alignment alignment)
        {
            alignment = new Alignment();
            int bestV = 0, bestW = 0, best = 0;

            LastOp[,] action = new LastOp[v.Length + 1, w.Length + 1];
            int[,] matrix    = new int[v.Length + 1, w.Length + 1];
            for (int i = 0; i <= v.Length; i++)
            {
                matrix[i, 0] = 0;
                action[i, 0] = LastOp.Skip;
            }
            for (int j = 0; j <= w.Length; j++)
            {
                matrix[0, j] = 0;
                action[0, j] = LastOp.Skip;
            }

            for (int i = 1; i <= v.Length; i++)
            {
                for (int j = 1; j <= w.Length; j++)
                {
                    var max = Maximum(
                        matrix[i - 1, j] + Epsilon,
                        matrix[i, j - 1] + Epsilon,
                        matrix[i - 1, j - 1] + Matrix[v[i - 1], w[j - 1]],
                        out action[i, j]
                        );
                    if (max > 0)
                    {
                        matrix[i, j] = max;
                        if (max > best)
                        {
                            best  = max;
                            bestV = i;
                            bestW = j;
                        }
                    }
                    else
                    {
                        action[i, j] = LastOp.Skip;
                        matrix[i, j] = 0;
                    }
                }
            }

            int           a = bestV, b = bestW;
            StringBuilder vRes = new StringBuilder();
            StringBuilder wRes = new StringBuilder();

            while (action[a, b] != LastOp.Skip)
            {
                switch (action[a, b])
                {
                case LastOp.GapV:
                    vRes.Append('-');
                    wRes.Append(w[b - 1]);
                    b--;
                    break;

                case LastOp.GapW:
                    vRes.Append(v[a - 1]);
                    wRes.Append('-');
                    a--;
                    break;

                case LastOp.Change:
                    vRes.Append(v[a - 1]);
                    wRes.Append(w[b - 1]);
                    a--; b--;
                    break;
                }
            }
            var alignedV = vRes.ToString().ToCharArray();

            Array.Reverse(alignedV);
            var alignedW = wRes.ToString().ToCharArray();

            Array.Reverse(alignedW);
            alignment.VStart   = a;
            alignment.WStart   = b;
            alignment.VEnd     = bestV;
            alignment.WEnd     = bestW;
            alignment.AlignedV = new string(alignedV);
            alignment.AlignedW = new string(alignedW);
            //-----------------------------------------
            //Console.WriteLine();
            //Console.WriteLine("Alignment with cost: {0}", matrix[v.Length, w.Length]);
            //Console.WriteLine("Word v: {0}", alignment.AlignedV);
            //Console.WriteLine("Word w: {0}", alignment.AlignedW);
            //-----------------------------------------
            return(matrix[bestV, bestW]);
        }