Ниже приведена базовая реализация R.
Если вы хотите найти максимальную квадратную подматрицу в неквадратной матрице, вы можете попробовать следующий код:
r <- list()
for (w in rev(seq(min(dim(M))))) {
for (rs in seq(nrow(M)-w+1)) {
for (cs in seq(ncol(M)-w+1)) {
mat <- M[rs-1+(1:w),cs-1+(1:w)]
u <- unique(c(mat))
if (all(u!=0) &length(u)==1) r[[length(r)+1]] <- mat
}
}
if (length(r)>0) break
}
такое, что
> r
[[1]]
[,1] [,2]
[1,] 3 3
[2,] 3 3
[[2]]
[,1] [,2]
[1,] 2 2
[2,] 2 2
[[3]]
[,1] [,2]
[1,] 3 3
[2,] 3 3
[[4]]
[,1] [,2]
[1,] 2 2
[2,] 2 2
[[5]]
[,1] [,2]
[1,] 1 1
[2,] 1 1
[[6]]
[,1] [,2]
[1,] 1 1
[2,] 1 1
[[7]]
[,1] [,2]
[1,] 3 3
[2,] 3 3
[[8]]
[,1] [,2]
[1,] 3 3
[2,] 3 3
ДАННЫЕ
M <- structure(c(1L, 3L, 1L, 2L, 1L, 3L, 3L, 2L, 2L, 3L, 3L, 1L, 1L,
1L, 2L, 2L, 2L, 2L, 3L, 1L, 3L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 2L,
2L, 2L, 1L, 3L, 1L, 3L, 2L, 2L, 2L, 2L, 3L, 2L, 1L, 3L, 2L, 1L,
1L, 3L, 2L, 2L, 3L, 3L, 2L, 2L, 2L, 2L, 1L, 2L, 2L, 2L, 2L, 1L,
3L, 3L, 2L, 3L, 3L, 2L, 3L, 3L, 1L, 1L, 1L, 1L, 3L, 2L, 3L, 1L,
1L, 2L, 1L, 1L, 1L, 1L, 3L, 2L, 1L, 1L, 3L, 3L, 3L, 2L, 2L, 2L,
3L, 2L, 2L, 3L, 3L, 3L, 1L, 2L, 2L, 1L, 3L, 3L, 2L, 3L, 2L, 1L,
2L, 1L, 3L, 3L, 1L, 2L, 1L, 3L, 2L, 3L, 3L, 1L, 1L, 2L, 2L, 2L,
1L, 1L, 1L, 2L, 1L, 3L, 2L, 3L, 3L, 2L, 3L, 3L, 1L, 1L, 2L, 2L,
1L, 2L, 3L, 3L, 3L, 3L, 3L, 1L, 3L), .Dim = c(15L, 10L))
> M
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 2 2 1 1 3 2 2 1 3
[2,] 3 2 1 3 3 1 2 3 1 3
[3,] 1 2 3 2 3 1 2 2 2 1
[4,] 2 3 1 2 2 2 3 1 2 1
[5,] 1 1 3 3 3 1 2 2 2 2
[6,] 3 3 2 3 3 1 2 1 1 2
[7,] 3 1 2 2 2 1 3 3 1 1
[8,] 2 1 2 2 3 1 3 3 1 2
[9,] 2 1 2 2 3 3 3 1 2 3
[10,] 3 1 3 2 1 2 1 2 1 3
[11,] 3 2 2 1 1 1 2 1 3 3
[12,] 1 1 1 2 1 1 2 3 2 3
[13,] 1 1 3 2 1 3 1 2 3 3
[14,] 1 2 2 2 3 3 3 3 3 1
[15,] 2 2 1 2 2 3 3 3 2 3
РЕДАКТИРОВАТЬ
Приведенный выше подход неэффективен, когда с большая матрица, так как все комбинации проверены. Приведенный ниже метод представляет собой R
реализацию алгоритма, указанного в https://www.geeksforgeeks.org/maximum-size-sub-matrix-with-all-1s-in-a-binary-matrix/, что намного эффективнее.
M <- unname(as.matrix(read.csv(file = "test2.csv")))
S <- matrix(0,nrow = nrow(M),ncol = ncol(M))
S[,1] <- M[,1]
for (i in 1:nrow(S)) {
for (j in 2:ncol(S)) {
if (M[i,j]==1) {
if (i==1) {
S[i,j] <- M[i,j]
} else {
S[i,j] <- min(c(S[i,j-1],S[i-1,j],S[i-1,j-1]))+1
}
}
}
}
inds <- which(S == max(S),arr.ind = TRUE)
w <- seq(max(S))-1
res <- lapply(seq(nrow(inds)), function(k) M[inds[k,"row"]-w,inds[k,"col"]-w])