[英]Counting and changing the 0s in a matrix that are surrounded by 1s - Python
我正在研究一个粒子系统模拟,其中成千上万的粒子随机游走,直到它们附着到一个不断增长的集群上。 为了可视化这个集群,我将集群粒子位置作为 1 存储在 numpy 数组中,该数组最初充满 0,然后使用matshow
function。 0 为白色,1 为黑色。
我注意到在这些模拟中可能会发生以下情况(实际的 arrays 要大得多,1000x1000 或更大):
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 1., 1., 1., 1., 0., 0., 0.],
[0., 0., 1., 1., 1., 1., 1., 1., 0., 0.],
[0., 0., 1., 1., 0., 0., 1., 1., 0., 0.],
[0., 0., 1., 1., 0., 0., 1., 1., 0., 0.],
[0., 0., 1., 1., 1., 1., 1., 1., 0., 0.],
[0., 0., 0., 1., 1., 1., 1., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])
其中粒子(1s)以这样的方式附着,从而形成一个“口袋”(0s)。 在这些星团的图像中,它们显示为小孔。 这是较小集群的样子:
如果你眯着眼睛,你可以看到我所说的一些“洞”。 这些对应于在相关的 numpy 阵列中完全被 1 包围的 0。
我的问题:我怎样才能写一个 function :
我第一次编写这样的 function 适用于小型/简单 arrays ,如上面的示例,但无法在模拟中适用于实际集群 arrays:
def holes(matrix):
num_holes = 0
for row in range(matrix.shape[0]):
for col in range(matrix.shape[0]):
if matrix[row, col] == 0:
can_escape = True
path_down = matrix[row, col:]
path_up = np.flip(matrix[:row+1, col])
path_right = matrix[row:, col]
path_left = np.flip(matrix[row, :col+1])
if 1 in path_down[1:] and 1 in path_up[1:] and 1 in path_left[1:] and 1 in path_right[1:]:
can_escape = False
if can_escape is False:
matrix[row, col] = -1
num_holes += 1
return num_holes
我认识到这个 function 将无法在这种情况下执行我希望它执行的操作,即发生“裂缝”:
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 1., 0., 1., 1., 1., 1., 0., 0.],
[0., 0., 1., 0., 0., 0., 1., 1., 0., 0.],
[0., 0., 1., 0., 0., 0., 1., 1., 0., 0.],
[0., 0., 1., 0., 1., 1., 1., 1., 0., 0.],
[0., 0., 0., 1., 1., 1., 1., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])
调用我的尝试将给出:
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 1., 0., 1., 1., 1., 1., 0., 0.],
[0., 0., 1., 0., -1., -1., 1., 1., 0., 0.],
[0., 0., 1., 0., -1., -1., 1., 1., 0., 0.],
[0., 0., 1., 0., 1., 1., 1., 1., 0., 0.],
[0., 0., 0., 1., 1., 1., 1., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])
这是不正确的,因为这个配置实际上并没有一个 0 的口袋。
我怎样才能正确地并且可能有效地做到这一点? 就像我说的,模拟在 arrays 上运行,至少大小为 1000x1000。
您可以使用洪水填充算法。
该算法的工作原理类似于绘画中的“填充”功能,并在图像中查找具有相同颜色的所有像素。 使用它用 -1 替换所有外部零,而不是用 1 替换所有剩余的零,而不是将所有 -1 变为零。
以这个答案为基础,实现洪水填充,您的算法将类似于:
def floodfill(matrix, x, y, original_value, new_value):
if matrix[x][y] == original_value:
matrix[x][y] = new_value
#recursively invoke flood fill on all surrounding cells:
if x > 0:
floodfill(matrix,x-1,y)
if x < len(matrix[y]) - 1:
floodfill(matrix,x+1,y)
if y > 0:
floodfill(matrix,x,y-1)
if y < len(matrix) - 1:
floodfill(matrix,x,y+1)
def main():
# Assuming 0, 0 has 0 in it - turning all the outside zeros to -1
floodfill(matrix, 0, 0, 0, -1)
for i in range(len(matrix)):
for j in range(len(matrix[i])):
if matrix[i][j] == -1:
matrix[i][j] = 0
if matrix[i][j] == 0:
matrix[i][j] = 1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.