[英]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.jl
的label_components
確實是解決核心問題的最簡單方法。 但是,超過1:maximum(labels)
循環可能效率不高:它是O(N*n)
,其中N
是labels
中元素的數量, 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代碼):
在偽代碼中(使用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.