我有一个看起来如下的数组:
numpy
我希望每个连续的区域都标记为
arr = np.array([[-1, -1, -1, 0, -1]
[ -1, -1, -1, 0, -1]
[ -1, 0, -1, -1, 0]
[ -1, 0, -1, -1, -1]
[ -1, -1, -1, -1, 0]])
(包括对角线),以更改为不同的值,以便我的数组最终看起来像这样:
0
一种做到这一点的方式可能是通过广度优先搜索。有什么方便的方法可以做到这一点,还是有一种更轻松的方法可用?
这个问题确实看起来像是广度优先搜索的好候选人。
指南中改编的一种工作方法,它讨论了一个类似的问题。 首先,这可能有助于提供一些语义,以实现“方向”的含义。这完全是可选的 - 但可能有助于理解问题。
arr = np.array([[ -1, -1, -1, 1, -1]
[ -1, -1, -1, 1, -1]
[ -1, 2, -1, -1, 1]
[ -1, 2, -1, -1, -1]
[ -1, -1, -1, -1, 3]])
表示“左上角”,因为它是带有行索引和列索引的单元格,相对于您正在查看的单元格。
(-1, -1)
next,您想创建一个数数and,以帮助记住您发现的哪些孔。每个“访问的单元格”都是一个元组(-1
,而第二个元组是孔数。每次找到一个洞时,都会开始进行广度优先搜索以弄清楚该洞有多大。
-1
活动广度优先搜索实例化了一个包含新的相邻“孔”细胞的队列。如果我们找到一个新的相邻零,那么搜索将继续,以便我们可以发现孔的外围。
class Direction:
def __init__(self, row, column, name):
self.row = row
self.column = column
self.name = name
directions = [
Direction(row=-1, column=-1, name="top-left"),
Direction(row=-1, column=0, name="top"),
Direction(row=-1, column=1, name="top-right"),
Direction(row=0, column=1, name="right"),
Direction(row=1, column=1, name="bottom-right"),
Direction(row=1, column=0, name="bottom"),
Direction(row=1, column=-1, name="bottom-left"),
Direction(row=0, column=-1, name="left")
]
我们需要知道单元格是否在我们正在查看的单元格的方向上是否是阵列的内部界限,而无需碰到visited_cells
。如果是这样,那么我们需要知道它是否是我们孔的延伸。我们还需要知道我们是否已经看到了这个细胞。
(False, -1)
将它们全部结合在一起,您可以生成一个新的“孔图”:
def count_holes(cells):
visited_cells = [[(False, 0) for x in range(0, len(cells))] for y in range(0, len(cells[0]))]
hole_number = 0
for i in range(0, len(cells)):
for j in range(0, len(cells[0])):
if visited_cells[i][j][0]:
continue
if cells[i][j] == 0:
hole_number += 1
do_breadth_first_search(cells, visited_cells, i, j, hole_number)
return visited_cells