簡體   English   中英

計算和更改被 1 包圍的矩陣中的 0 - Python

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

  1. 計算完全被 1 包圍的 0 的數量
  2. 將完全被 1 包圍的 0 更改為 -1(我有理由希望它們改為 -1)

我第一次編寫這樣的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM