private MiddleSnake FindMiddleSnake(Sequence src, Sequence des) { int d, k; int x, y; var midSnake = new MiddleSnake(); // the range of diagonal values var minDiag = src.StartIndex - des.EndIndex; var maxDiag = src.EndIndex - des.StartIndex; // middle point of forward searching var fwdMid = src.StartIndex - des.StartIndex; // middle point of backward searching var bwdMid = src.EndIndex - des.EndIndex; // forward seaching range var fwdMin = fwdMid; var fwdMax = fwdMid; // backward seaching range var bwdMin = bwdMid; var bwdMax = bwdMid; var odd = ((fwdMin - bwdMid) & 1) == 1; _fwdVector[fwdMid] = src.StartIndex; _bwdVector[bwdMid] = src.EndIndex; for (d = 1; ; d++) { // extend or shrink the search range if (fwdMin > minDiag) { _fwdVector[--fwdMin - 1] = -1; } else { ++fwdMin; } if (fwdMax < maxDiag) { _fwdVector[++fwdMax + 1] = -1; } else { --fwdMax; } // top-down search for (k = fwdMax; k >= fwdMin; k -= 2) { if (_fwdVector[k - 1] < _fwdVector[k + 1]) { x = _fwdVector[k + 1]; } else { x = _fwdVector[k - 1] + 1; } y = x - k; midSnake.Source.StartIndex = x; midSnake.Destination.StartIndex = y; while (x < src.EndIndex && y < des.EndIndex && _original[x].CompareTo(_modified[y]) == 0) { x++; y++; } // update forward vector _fwdVector[k] = x; if (!odd || k < bwdMin || k > bwdMax || x < _bwdVector[k]) { continue; } // this is the snake we are looking for // and set the end indexes of the snake midSnake.Source.EndIndex = x; midSnake.Destination.EndIndex = y; midSnake.SesLength = 2 * d - 1; return(midSnake); } // extend the search range if (bwdMin > minDiag) { _bwdVector[--bwdMin - 1] = int.MaxValue; } else { ++bwdMin; } if (bwdMax < maxDiag) { //test the index rage before assigning it var iBwdMaxTry = ++bwdMax + 1; //if (bwdVector.data.Length > (bwdVector.N + iBwdMaxTry)) _bwdVector[iBwdMaxTry] = int.MaxValue; //else // --bwdMax; } else { --bwdMax; } // bottom-up search for (k = bwdMax; k >= bwdMin; k -= 2) { if (_bwdVector[k - 1] < _bwdVector[k + 1]) { x = _bwdVector[k - 1]; } else { x = _bwdVector[k + 1] - 1; } y = x - k; midSnake.Source.EndIndex = x; midSnake.Destination.EndIndex = y; while (x > src.StartIndex && y > des.StartIndex && _original[x - 1].CompareTo(_modified[y - 1]) == 0) { x--; y--; } // update backward Vector _bwdVector[k] = x; if (odd || k < fwdMin || k > fwdMax || x > _fwdVector[k]) { continue; } // this is the snake we are looking for // and set the start indexes of the snake midSnake.Source.StartIndex = x; midSnake.Destination.StartIndex = y; midSnake.SesLength = 2 * d; return(midSnake); } } }
/// <summary> /// In the edit graph for the sequences src and des, search for the /// optimal(shortest) path from (src.StartIndex, des.StartIndex) to /// (src.EndIndex, des.EndIndex). /// /// The searching starts from both ends of the graph and when the /// furthest forward reaching overlaps with the furthest backward /// reaching, the overlapped point is reported as the middle point /// of the shortest path. /// /// See the listed reference for the detailed description of the /// algorithm /// </summary> /// <param name="src"> /// Represents a (sub)sequence of _original /// </param> /// <param name="des"> /// Represents a (sub)sequence of _modified /// </param> /// <returns> /// The found middle snake /// </returns> private MiddleSnake FindMiddleSnake(Sequence src, Sequence des) { int d, k; int x, y; MiddleSnake midSnake = new MiddleSnake(); // the range of diagonal values int minDiag = src.StartIndex - des.EndIndex; int maxDiag = src.EndIndex - des.StartIndex; // middle point of forward searching int fwdMid = src.StartIndex - des.StartIndex; // middle point of backward searching int bwdMid = src.EndIndex - des.EndIndex; // forward seaching range int fwdMin = fwdMid; int fwdMax = fwdMid; // backward seaching range int bwdMin = bwdMid; int bwdMax = bwdMid; bool odd = ((fwdMin - bwdMid) & 1) == 1; fwdVector[fwdMid] = src.StartIndex; bwdVector[bwdMid] = src.EndIndex; #if (MyDEBUG) Debug.WriteLine("-- Entering Function findMiddleSnake(src, des) --"); #endif for (d = 1; ; d++) { // extend or shrink the search range if (fwdMin > minDiag) { fwdVector[--fwdMin - 1] = -1; } else { ++fwdMin; } if (fwdMax < maxDiag) { fwdVector[++fwdMax + 1] = -1; } else { --fwdMax; } #if (MyDEBUG) Debug.WriteLine(d, " D path"); #endif // top-down search for (k = fwdMax; k >= fwdMin; k -= 2) { if (fwdVector[k - 1] < fwdVector[k + 1]) { x = fwdVector[k + 1]; } else { x = fwdVector[k - 1] + 1; } y = x - k; midSnake.Source.StartIndex = x; midSnake.Destination.StartIndex = y; while (x < src.EndIndex && y < des.EndIndex && _original[x].CompareTo(_modified[y]) == 0) { x++; y++; } // update forward vector fwdVector[k] = x; #if (MyDEBUG) Debug.WriteLine(" Inside forward loop"); Debug.WriteLine(k, " Diagonal value"); Debug.WriteLine(x, " X value"); Debug.WriteLine(y, " Y value"); #endif if (odd && k >= bwdMin && k <= bwdMax && x >= bwdVector[k]) { // this is the snake we are looking for // and set the end indeses of the snake midSnake.Source.EndIndex = x; midSnake.Destination.EndIndex = y; midSnake.SES_Length = 2 * d - 1; #if (MyDEBUG) Debug.WriteLine("!!!Report snake from forward search"); Debug.WriteLine(midSnake.Source.StartIndex, " middle snake source start index"); Debug.WriteLine(midSnake.Source.EndIndex, " middle snake source end index"); Debug.WriteLine(midSnake.Destination.StartIndex, " middle snake destination start index"); Debug.WriteLine(midSnake.Destination.EndIndex, " middle snake destination end index"); #endif return(midSnake); } } // extend the search range if (bwdMin > minDiag) { bwdVector[--bwdMin - 1] = int.MaxValue; } else { ++bwdMin; } if (bwdMax < maxDiag) { bwdVector[++bwdMax + 1] = int.MaxValue; } else { --bwdMax; } // bottom-up search for (k = bwdMax; k >= bwdMin; k -= 2) { if (bwdVector[k - 1] < bwdVector[k + 1]) { x = bwdVector[k - 1]; } else { x = bwdVector[k + 1] - 1; } y = x - k; midSnake.Source.EndIndex = x; midSnake.Destination.EndIndex = y; while (x > src.StartIndex && y > des.StartIndex && _original[x - 1].CompareTo(_modified[y - 1]) == 0) { x--; y--; } // update backward Vector bwdVector[k] = x; #if (MyDEBUG) Debug.WriteLine(" Inside backward loop"); Debug.WriteLine(k, " Diagonal value"); Debug.WriteLine(x, " X value"); Debug.WriteLine(y, " Y value"); #endif if (!odd && k >= fwdMin && k <= fwdMax && x <= fwdVector[k]) { // this is the snake we are looking for // and set the start indexes of the snake midSnake.Source.StartIndex = x; midSnake.Destination.StartIndex = y; midSnake.SES_Length = 2 * d; #if (MyDEBUG) Debug.WriteLine("!!!Report snake from backward search"); Debug.WriteLine(midSnake.Source.StartIndex, " middle snake source start index"); Debug.WriteLine(midSnake.Source.EndIndex, " middle snake source end index"); Debug.WriteLine(midSnake.Destination.StartIndex, " middle snake destination start index"); Debug.WriteLine(midSnake.Destination.EndIndex, " middle snake destination end index"); #endif return(midSnake); } } } }
/// <summary> /// In the edit graph for the sequences src and des, search for the /// optimal(shortest) path from (src.StartIndex, des.StartIndex) to /// (src.EndIndex, des.EndIndex). /// /// The searching starts from both ends of the graph and when the /// furthest forward reaching overlaps with the furthest backward /// reaching, the overlapped point is reported as the middle point /// of the shortest path. /// /// See the listed reference for the detailed description of the /// algorithm /// </summary> /// <param name="src"> /// Represents a (sub)sequence of _original /// </param> /// <param name="desc"> /// Represents a (sub)sequence of _modified /// </param> /// <returns> /// The found middle snake /// </returns> private MiddleSnake FindMiddleSnake(Sequence src, Sequence des) { int d, k; int x, y; MiddleSnake midSnake = new MiddleSnake(); // the range of diagonal values int minDiag = src.StartIndex - des.EndIndex; int maxDiag = src.EndIndex - des.StartIndex; // middle point of forward searching int fwdMid = src.StartIndex - des.StartIndex; // middle point of backward searching int bwdMid = src.EndIndex - des.EndIndex; // forward seaching range int fwdMin = fwdMid; int fwdMax = fwdMid; // backward seaching range int bwdMin = bwdMid; int bwdMax = bwdMid; bool odd = ((fwdMin - bwdMid) & 1) == 1; fwdVector[fwdMid] = src.StartIndex; bwdVector[bwdMid] = src.EndIndex; #if (MyDEBUG) Debug.WriteLine("-- Entering Function findMiddleSnake(src, des) --"); #endif for (d = 1; ; d++) { // extend or shrink the search range if (fwdMin > minDiag) fwdVector[--fwdMin - 1] = -1; else ++fwdMin; if (fwdMax < maxDiag) fwdVector[++fwdMax + 1] = -1; else --fwdMax; #if (MyDEBUG) Debug.WriteLine(d, " D path"); #endif // top-down search for (k = fwdMax; k >= fwdMin; k -= 2) { if (fwdVector[k - 1] < fwdVector[k + 1]) { x = fwdVector[k + 1]; } else { x = fwdVector[k - 1] + 1; } y = x - k; midSnake.Source.StartIndex = x; midSnake.Destination.StartIndex = y; while (x < src.EndIndex && y < des.EndIndex && _original[x].CompareTo(_modified[y]) == 0) { x++; y++; } // update forward vector fwdVector[k] = x; #if (MyDEBUG) Debug.WriteLine(" Inside forward loop"); Debug.WriteLine(k, " Diagonal value"); Debug.WriteLine(x, " X value"); Debug.WriteLine(y, " Y value"); #endif if (odd && k >= bwdMin && k <= bwdMax && x >= bwdVector[k]) { // this is the snake we are looking for // and set the end indeses of the snake midSnake.Source.EndIndex = x; midSnake.Destination.EndIndex = y; midSnake.SES_Length = 2 * d - 1; #if (MyDEBUG) Debug.WriteLine("!!!Report snake from forward search"); Debug.WriteLine(midSnake.Source.StartIndex, " middle snake source start index"); Debug.WriteLine(midSnake.Source.EndIndex, " middle snake source end index"); Debug.WriteLine(midSnake.Destination.StartIndex, " middle snake destination start index"); Debug.WriteLine(midSnake.Destination.EndIndex, " middle snake destination end index"); #endif return midSnake; } } // extend the search range if (bwdMin > minDiag) bwdVector[--bwdMin - 1] = int.MaxValue; else ++bwdMin; if (bwdMax < maxDiag) bwdVector[++bwdMax + 1] = int.MaxValue; else --bwdMax; // bottom-up search for (k = bwdMax; k >= bwdMin; k -= 2) { if (bwdVector[k - 1] < bwdVector[k + 1]) { x = bwdVector[k - 1]; } else { x = bwdVector[k + 1] - 1; } y = x - k; midSnake.Source.EndIndex = x; midSnake.Destination.EndIndex = y; while (x > src.StartIndex && y > des.StartIndex && _original[x - 1].CompareTo(_modified[y - 1]) == 0) { x--; y--; } // update backward Vector bwdVector[k] = x; #if (MyDEBUG) Debug.WriteLine(" Inside backward loop"); Debug.WriteLine(k, " Diagonal value"); Debug.WriteLine(x, " X value"); Debug.WriteLine(y, " Y value"); #endif if (!odd && k >= fwdMin && k <= fwdMax && x <= fwdVector[k]) { // this is the snake we are looking for // and set the start indexes of the snake midSnake.Source.StartIndex = x; midSnake.Destination.StartIndex = y; midSnake.SES_Length = 2 * d; #if (MyDEBUG) Debug.WriteLine("!!!Report snake from backward search"); Debug.WriteLine(midSnake.Source.StartIndex, " middle snake source start index"); Debug.WriteLine(midSnake.Source.EndIndex, " middle snake source end index"); Debug.WriteLine(midSnake.Destination.StartIndex, " middle snake destination start index"); Debug.WriteLine(midSnake.Destination.EndIndex, " middle snake destination end index"); #endif return midSnake; } } } }