Consider the following simplified example, with all possible 2 x 2 matrices with one 1 and the remaining 0s.
library(arrangements)
# define function
generate_matrices <- function(nrow, ncol, ones_count) {
vectors <- permutations(c(
rep(1, ones_count),
rep(0, nrow * ncol - ones_count)
))
# remove redundancies
vectors <- vectors[!duplicated(vectors),]
# list of matrices
out <- list()
for (i in 1:ncol(vectors)) {
out[[i]] <- matrix(
data = vectors[,i],
nrow = nrow,
ncol = ncol,
byrow = TRUE
)
}
return(out)
}
Run function to generate all 2 by 2 matrices with one 1:
generate_matrices(nrow = 2, ncol = 2, ones_count = 1)
[[1]]
[,1] [,2]
[1,] 1 0
[2,] 0 0
[[2]]
[,1] [,2]
[1,] 0 1
[2,] 0 0
[[3]]
[,1] [,2]
[1,] 0 0
[2,] 1 0
[[4]]
[,1] [,2]
[1,] 0 0
[2,] 0 1
When I extend this to a matrix with 5 rows, 4 columns and 4 ones, it errors:
generate_matrices(nrow = 5, ncol = 4, ones_count = 4)
# Error in permutations(c(rep(1, ones_count), rep(0, nrow * ncol - ones_count))) :
# too many results
My guess is that the lines
vectors <- permutations(c(
rep(1, ones_count),
rep(0, nrow * ncol - ones_count)
))
takes too long to run and/or there is not enough memory on my laptop to store these. Is there a more efficient way to implement this?
It is worth noting that I would like to eventually extend this to the 6 x 5 case with 4 ones, and 8 x 5 case with 8 ones.
You can take combination of indices on which is 1:
m <- 2
n <- 2
k <- 2
createMatrix <- function(m, n, indices){
x <- matrix(0, m, n)
x[indices] <- 1
x
}
lapply(
combn(seq_len(m*n), k, simplify = FALSE),
function(x) createMatrix(m, n, x)
)
where m
is number of rows, n
number of columns and k
number of ones.
You could use the function developed here to get all possible matrices of dim 5x4, and then filter by the number of 1s using sum
.
f = function(nrow, ncol) lapply(asplit(do.call(expand.grid, rep(list(0:1), nrow * ncol)), 1), matrix, nrow, ncol)
list = f(5,4)
list[lapply(list, sum) == 4]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With