简体   繁体   English

找到最短的水距离

[英]Finding shortest distance to water

I have a two-dimensional map of land and water, like the following ( l representing land and w representing water). 我有一张土地和水的二维地图,如下图所示( l代表土地, w代表水)。

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): 我们可以做类似以下的事情(类似于BFS,但可能有多个来源):

Have a queue (FIFO) initially empty. 队列(FIFO)最初为空。 Have another mxn grid D of distances with all elements initialized to infinity. 有另一个mxn网格D的距离,所有元素都初始化为无穷大。

  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). 遍历所有区块并推动队列中水瓦片的位置(如果网格为mxn,则将采用O(mn))。 Also, have D[pos] <- 0 for all water tile positions. 此外,对于所有水瓦位置,D [pos] < - 0。
  2. While queue is not empty do the following: 2.1. 队列不为空时,请执行以下操作:2.1。 Pop a tile t from the queue. 从队列中弹出一个tile t。 2.2. 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. 检查所有相邻的瓷砖t_a(左,右,顶部,底部,对角线,也考虑角部情况,应在O(1)时间内找到),并检查D [t_a]> D [t] + 1然后D [t_a] < - D [t] + 1并将t_a推入队列。

Step 2 should not take more than O(mn) time for a mxn grid. 对于mxn网格,步骤2的时间不应超过O(mn)。

Do a breadth-first-search over all the tiles in the map, starting with the water tiles as roots and following edges to neighboring tiles. 对地图中的所有图块进行广度优先搜索,从水砖作为根,然后沿着边缘到相邻图块。 The level at which you you find a tile will be its distance from water. 找到瓷砖的水平将是它与水的距离。

See this answer for a nice way to keep track of the depth during BFS: 请参阅此答案,了解在BFS期间跟踪深度的好方法:

How to keep track of BFS depth in C++ 如何在C ++中跟踪BFS深度

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM