// See if a point is in the current path mode section private bool PointInPath(DistPoint C_p) { bool blnInPath = false; foreach (DistPoint p in lstCurPath) { if (p.row == C_p.row && p.column == C_p.column) { blnInPath = true; break; } } return blnInPath; }
// LHC Algorithm to identify modes private void LocalHillClimbing(int C_i, int C_j) { // A new path now pathCount++; #region FindMode // Climb bool blnMode = false; while (!blnMode) { // Mark self as visited mVisited[C_i, C_j] = 1; // Label cell with current path count mPaths[C_i, C_j] = pathCount; // Loop through all unvisited neighbors to see if there's someone same or better bool blnMoved = false; for (int i = C_i - 1; i < C_i + 2; i++) { if (i < 0 || i > max_r) { // No neighber in that direction } else { for (int j = C_j - 1; j < C_j + 2; j++) { if (j < 0 || j > max_c // No neighber in that direction || (i == C_i && j == C_j) // Don't compare against self || mVisited[i, j] == 1) // Don't worry about visited cell { // No valid neighbor in this direction. } else { // There is an unvisited neightbor // If same or better, move to it. if (mSmallerMap[C_i, C_j] <= mSmallerMap[i, j]) { if (mSmallerMap[C_i, C_j] == mSmallerMap[i, j]) { // If same, then remember it DistPoint p = new DistPoint(); p.row = C_i; p.column = C_j; lstCurPath.Add(p); } else { // If next point is better, clear the list lstCurPath.Clear(); } // Move to this neighbor blnMoved = true; C_i = i; C_j = j; // Make sure I am done with this round i = C_i + 2; j = C_j + 2; } } } } } if (!blnMoved) { // No better neighbor, so I am the mode. blnMode = true; } } #endregion #region ValidateMode // Mark self as visited mVisited[C_i, C_j] = 1; // Label cell with current path count mPaths[C_i, C_j] = pathCount; // Add self to path (mode section) DistPoint C_p = new DistPoint(); C_p.row = C_i; C_p.column = C_j; lstCurPath.Add(C_p); //// Debug //Console.Write("\n"); //Console.Write("mModes:\n"); //for (int i = 0; i < mModes.Rows; i++) //{ // for (int j = 0; j < mModes.Columns; j++) // { // Console.Write(mModes[i, j].ToString() + " "); // } // Console.Write("\n"); //} //Console.Write("Paths:\n"); //for (int i = 0; i < mPaths.Rows; i++) //{ // for (int j = 0; j < mPaths.Columns; j++) // { // Console.Write(mPaths[i, j].ToString() + " "); // } // Console.Write("\n"); //} // Now let's see if this is really a mode bool blnRealMode = true; // Make sure I am really the mode by checking all visited neighbors along the path (mode section) float otherMode = -1; foreach (DistPoint p in lstCurPath) { if (!blnRealMode) { // As soon as we find a connected mode, stop the loop. break; } for (int i = p.row - 1; i < p.row + 2; i++) { if (i < 0 || i > max_r) { // No neighber in that direction } else { for (int j = p.column - 1; j < p.column + 2; j++) { DistPoint pp = new DistPoint(); pp.row = i; pp.column = j; if (j < 0 || j > max_c // No neighber in that direction || (i == p.row && j == p.column) // Don't compare against self || PointInPath(pp) // Don't check this path because it doesn't have mode label yet. || mVisited[i, j] == 0) // Only check visited nodes { // No valid neighbor } else { if (mSmallerMap[p.row, p.column] <= mSmallerMap[i, j]) { // I am not a real mode blnRealMode = false; if (mSmallerMap[p.row, p.column] == mSmallerMap[i, j] && mModes[i, j] >= 0) { // I am part of another mode otherMode = mModes[i, j]; } // Make sure I am done. i = p.row + 2; j = p.column + 2; } } } } } } if (blnRealMode) { Count++; } #endregion // Connected-Component-Labeling if (blnRealMode) { // If I am the real mode, then mark all past cells on path with same height the new modeCount value. foreach (DistPoint p in lstCurPath) { mModes[p.row, p.column] = Count; } } else { if (otherMode > 0) { foreach (DistPoint p in lstCurPath) { mModes[p.row, p.column] = otherMode; } } } // Clear list lstCurPath.Clear(); }