簡體   English   中英

如何使用Julia在矩陣中查找連接的組件

[英]How to find connected components in a matrix using Julia

假設我有以下矩陣(在Julia語言中定義):

    mat = [1 1 0 0 0 ; 1 1 0 0 0 ; 0 0 0 0 1 ; 0 0 0 1 1]

將一組具有值“1”的相鄰元素視為“組件”,如何識別該矩陣具有2個組件以及哪個頂點組成每個組件?

對於上面的矩陣 ,我想找到以下結果:

組件1由矩陣的以下元素(行,列)組成:

    (1,1)
    (1,2)
    (2,1)
    (2,2)

組件2由以下元素組成:

    (3,5)
    (4,4)
    (4,5)

我可以使用圖形算法,如識別方陣組成部分。 然而,這樣的算法不能用於非方形矩陣,就像我在這里提出的那樣。

任何想法將不勝感激。

如果你的建議涉及使用Python庫+ PyCall,我是開放的。 雖然我更喜歡使用純Julia解決方案。

問候

使用Image.jllabel_components確實是解決核心問題的最簡單方法。 但是,超過1:maximum(labels)循環可能效率不高:它是O(N*n) ,其中Nlabels中元素的數量, n是最大值,因為您訪問labels每個元素n次。

只需兩次訪問labels每個元素,你會好得多:一次確定最大值,一次將每個非零元素分配給其正確的組:

using Images

function collect_groups(labels)
    groups = [Int[] for i = 1:maximum(labels)]
    for (i,l) in enumerate(labels)
        if l != 0
            push!(groups[l], i)
        end
    end
    groups
end

mat = [1 1 0 0 0 ; 1 1 0 0 0 ; 0 0 0 0 1 ; 0 0 0 1 1]

labels = label_components(mat)
groups = collect_groups(labels)

測試矩陣的輸出:

2-element Array{Array{Int64,1},1}:
 [1,2,5,6] 
 [16,19,20]

調用像find這樣的庫函數偶爾會很有用,但它也是一種習慣於慢速語言的習慣,值得留下。 在朱莉婭,你可以編寫自己的循環,它們會很快; 更好的是,通常生成的算法更容易理解。 collect(zip(ind2sub(size(mat),find( x -> x == value, mat))...))並沒有完全滾出舌頭。

答案很簡單(雖然我不能提供python代碼):

  1. 將所有1收集到列表中
  2. 選擇在步驟1中生成的列表的任意元素,並使用任意圖形遍歷算法遍歷所有鄰居1並從步驟1中生成的列表中刪除訪問過的1
  3. 重復步驟2,直到步驟1中生成的列表為空

在偽代碼中(使用BFS):

//generate a list with the position of all 1s in the matrix
list pos
for int x in [0 , matrix_width[
    for int y in [0 , matrix_height[
        if matrix[x][y] == 1
            add(pos , {x , y})

while NOT isempty(pos)
    //traverse the graph using BFS
    list visited
    list next

    add(next , remove(pos , 0))

    while NOT isempty(next)
        pair p = remove(next , 0)
        add(visited , p)
        remove(pos , p)

        //p is part of the specific graph that is processed in this BFS
        //each repetition of the outer while-loop process a different graph that is part 
        //of the matrix

        addall(next , distinct(visited , neighbour1s(p)))

剛從julia-users郵件列表中得到答案,使用Images.jl解決了這個問題,Images.jl是一個在Julia中處理圖像的庫。

他們開發了一個名為“label_components”的函數來識別矩陣中的連通分量。

然后我使用一個名為“findMat”的自定義函數來獲取每個組件的這種組件矩陣的索引。

答案,用Julia語言:

    using Images

    function findMat(mat,value)
        return(collect(zip(ind2sub(size(mat),find( x -> x == value, mat))...)));
    end

    mat = [1 1 0 0 0 ; 1 1 0 0 0 ; 0 0 0 0 1 ; 0 0 0 1 1]

    labels = label_components(mat);

    for c in 1:maximum(labels)
        comp = findMat(labels,c);
        println("Component $c is composed by the following elements (row,col)");       
        println("$comp\n"); 
    end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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