hieuza

Max connected area in 0/1 array -- Deep First Search

Nov 17th, 2017
513
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.67 KB | None | 0 0
  1. # 2017-11-17
  2.  
  3. import random
  4. import sys  # To print without newline.
  5.  
  6. def print_array(a, rows, cols, pos_cell='# ', zero_cell='. '):
  7.   for r in xrange(rows):
  8.     for c in xrange(cols):
  9.       sys.stdout.write(pos_cell if a[r][c] else zero_cell)
  10.     sys.stdout.write('\n')
  11.    
  12.  
  13. def visit_and_count(a, rows, cols, visited, r, c, debug=False):
  14.   """Visit the input array a started from (r, c) with visiting states in visited.
  15.  
  16.  visited array will be updated with the visited elements.
  17.  
  18.  Return the area of the connected area started at (r, c).
  19.  """
  20.   visited[r][c] = True
  21.   if debug:
  22.     sys.stdout.write('Visiting (%d, %d)\n' % (r, c))
  23.  
  24.   area = 1  # Current cell.
  25.   dd = [(-1, 0), (0, 1), (1, 0), (0, -1)]
  26.   for dr, dc in dd:
  27.     next_row = r + dr
  28.     next_col = c + dc
  29.     # Only proceed with valid cell.
  30.     if next_row < 0 or next_row >= rows or next_col < 0 or next_col >= cols:
  31.       continue
  32.  
  33.     if a[next_row][next_col] == 1 and not visited[next_row][next_col]:
  34.       area += visit_and_count(a, rows, cols, visited, next_row, next_col, debug)
  35.  
  36.   return area
  37.  
  38.  
  39. def max_area_dfs(a, debug=False):
  40.   """Find the max area of connected 1s in a.
  41.  
  42.  Returns: max_area, start_col, start_row.
  43.  """
  44.  
  45.   rows = len(a)
  46.   if not rows:
  47.     return 0
  48.  
  49.   cols = len(a[0])
  50.  
  51.   visited = [[False] * cols for _ in xrange(rows)]
  52.   max_area = 0
  53.   # The coordiate of the start point of the max area.
  54.   start_row, start_col = -1, -1
  55.  
  56.   for r in xrange(rows):
  57.     for c in xrange(cols):
  58.       if a[r][c] == 1 and not visited[r][c]:
  59.         if debug:
  60.           sys.stdout.write('Starting from (%d, %d)\n' % (r, c))
  61.         area = visit_and_count(a, rows, cols, visited, r, c, debug)
  62.         if area > max_area:
  63.           max_area = area
  64.           start_row = r
  65.           start_col = c
  66.  
  67.   if debug:
  68.     sys.stdout.write('Visited array.\n')
  69.     print_array(visited, rows, cols)
  70.  
  71.   return max_area, start_row, start_col
  72.  
  73.  
  74. def main():
  75.   debug = False
  76.   rows = 7
  77.   cols = 7
  78.   a = [[0] * cols for _ in xrange(rows)]
  79.   # Randomly assign 1 to a.
  80.   for r in xrange(rows):
  81.     for c in xrange(cols):
  82.       a[r][c] = 1 if random.random() < 0.4 else 0
  83.  
  84.   sys.stdout.write('Input array:\n')
  85.   print_array(a, rows, cols)
  86.   max_area, start_row, start_col = max_area_dfs(a, debug=debug)
  87.  
  88.   sys.stdout.write('Max area: %d\n' % max_area)
  89.   sys.stdout.write('start_row: %d, start_col: %d\n' % (start_row, start_col))
  90.  
  91.   # Visualize the max area.
  92.   visited = [[False] * cols for _ in xrange(rows)]
  93.   visit_and_count(a, rows, cols, visited, start_row, start_col)
  94.   print_array(visited, rows, cols, pos_cell='O ')
  95.  
  96.  
  97. if __name__ == '__main__':
  98.   main()
Advertisement
Add Comment
Please, Sign In to add comment