[英]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.