3

Finding the shortest distance to water

 2 years ago
source link: https://www.codesd.com/item/finding-the-shortest-distance-to-water.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Finding the shortest distance to water

advertisements

I have a two-dimensional map of land and water, like the following (l representing land and w representing water).

lllwwwlll
lllwllllw
lllllllww
lllllllll

For each land tile, I want to know its distance from the nearest water tile. Moving horizontally, vertically, and diagonally all count as a distance of one.

321www111
321w1111w
3211121ww
322222111

Right now I am using an algorithm like so:

foreach tile in map
  if isWater(tile)
    tile.distanceFromWater = 0
  else
    radius = 1
    while !hasWaterAround(tile, radius)
      radius++
    tile.distanceFromWater = radius

This approach works, but it rather slow, especially when there are very few water tiles.

Is there a faster algorithm for finding the distance of each land tile from water?


We can do something like the following (similar to BFS, but starting possibly with multiple sources):

Have a queue (FIFO) initially empty. Have another mxn grid D of distances with all elements initialized to infinity.

  1. Traverse all the tiles and push (the positions of) the water tiles in the queue (this will take O(mn) if the grid is mxn). Also, have D[pos] <- 0 for all water tile positions.
  2. While queue is not empty do the following: 2.1. Pop a tile t from the queue. 2.2. Check all the adjacent tiles t_a (left, right, top, bottom, diagonal, also accounting for the corner cases, should be found in O(1) time), and check if D[t_a] > D[t] + 1 then D[t_a] <- D[t] + 1 and push t_a onto the queue.

Step 2 should not take more than O(mn) time for a mxn grid.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK