Tony Hellmuth
Tony Hellmuth

Reputation: 290

Find size of maximum connected region in matrix

So I have a matrix (n row by m column) and want to find the region with the most connected "1s". For example if I have the following matrix:

1 1 0 0
0 1 1 0
0 0 1 0
1 0 0 0

There are 2 regions of "1s" in the matrix.

1st region:

1 1
  1 1
    1

2nd region:

1

I would like to create an algorithm that will output the maximum = 5. I think this has something to do with Depth First Search but I only have base R and access to a few packages.

Upvotes: 3

Views: 686

Answers (2)

Tony Hellmuth
Tony Hellmuth

Reputation: 290

I did this eventually with use of igraph:

library(igraph)
data<-scan("stdin")
n<-data[1]
m<-data[2]

mat<-matrix(data[3:(n*m+2)],nrow=n,ncol=m,byrow=TRUE)
labels <- as.vector(mat)
rows <- (seq(length(labels)) - 1) %% nrow(mat)
cols <- ceiling(seq(length(labels)) / nrow(mat))
g <- graph.lattice(dim(mat), nei=2)

# Remove edges between elements of different types or that aren't diagonal
edgelist <- get.edgelist(g)
retain <- labels[edgelist[,1]] == labels[edgelist[,2]] &
  abs(rows[edgelist[,1]] - rows[edgelist[,2]]) <= 1 &
  abs(cols[edgelist[,1]] - cols[edgelist[,2]]) <= 1
g <- delete.edges(g, E(g)[!retain])

y<-clusters(g)$membership ### clustered matrix as vector
m<-as.vector(mat) ### original matrix 
z<-y[m>0] ### ignore where original matrix is 0
cat(sort(table(z),decreasing=TRUE)[[1]])

Upvotes: 2

DJack
DJack

Reputation: 4940

You could use SDMTools. First, we convert the matrix into raster, then we detect clumps (patches) of connected cells. Each clump gets a unique ID. NA and zero are used as background values. Finally, PatchStat provides statistics for each patch.

library(raster)
library(SDMTools)

r <- raster(mat)    
rc <- clump(r)
as.matrix(rc)
     [,1] [,2] [,3] [,4] [,5]
[1,]   NA    1    1    1    1
[2,]    1   NA   NA    1   NA
[3,]    1    1    1   NA    1
[4,]   NA   NA   NA   NA   NA
[5,]    2    2   NA   NA   NA
p <- PatchStat(rc)
max(p$n.cell)  

[1] 10

Sample data

set.seed(2)
m <- 5
n <- 5
mat <- round(matrix(runif(m * n), m, n))
mat
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    1    1    1    1
[2,]    1    0    0    1    0
[3,]    1    1    1    0    1
[4,]    0    0    0    0    0
[5,]    1    1    0    0    0

Upvotes: 3

Related Questions