/// <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 - 1)) { 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 - 1)) 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; } } } }