Ваш вопрос вдохновил меня попробовать написать обобщенную функцию, которая может генерировать список всех матриц размерности nr
по nc
, которые могут быть образованы с элементами данного вектора x
. Вот результат:
allmatrices <- function(x,nr,nc,...) {
nx <- length(x);
divs <- nx^seq(0L,nr*nc-1L);
lapply(seq(0L,nx^(nr*nc)-1L),function(i) matrix(x[i%/%divs%%nx+1L],nr,...));
}; ## end allmatrices()
Вот как вы можете использовать его, чтобы сгенерировать необходимую бинарную матрицу 2х2:
allmatrices(0:1,2L,2L);
## [[1]]
## [,1] [,2]
## [1,] 0 0
## [2,] 0 0
##
## [[2]]
## [,1] [,2]
## [1,] 1 0
## [2,] 0 0
##
## [[3]]
## [,1] [,2]
## [1,] 0 0
## [2,] 1 0
##
## [[4]]
## [,1] [,2]
## [1,] 1 0
## [2,] 1 0
##
## [[5]]
## [,1] [,2]
## [1,] 0 1
## [2,] 0 0
##
## [[6]]
## [,1] [,2]
## [1,] 1 1
## [2,] 0 0
##
## [[7]]
## [,1] [,2]
## [1,] 0 1
## [2,] 1 0
##
## [[8]]
## [,1] [,2]
## [1,] 1 1
## [2,] 1 0
##
## [[9]]
## [,1] [,2]
## [1,] 0 0
## [2,] 0 1
##
## [[10]]
## [,1] [,2]
## [1,] 1 0
## [2,] 0 1
##
## [[11]]
## [,1] [,2]
## [1,] 0 0
## [2,] 1 1
##
## [[12]]
## [,1] [,2]
## [1,] 1 0
## [2,] 1 1
##
## [[13]]
## [,1] [,2]
## [1,] 0 1
## [2,] 0 1
##
## [[14]]
## [,1] [,2]
## [1,] 1 1
## [2,] 0 1
##
## [[15]]
## [,1] [,2]
## [1,] 0 1
## [2,] 1 1
##
## [[16]]
## [,1] [,2]
## [1,] 1 1
## [2,] 1 1
Обратите внимание, что это приводит к идентичному выходу умного решения данны by @alexis_laz в своем комментарии:
identical(allmatrices(0:1,2L,2L),{ n <- 2; lapply(0:(((n*n)^2)-1),function(i) matrix(as.integer(head(intToBits(i),n*n)),n,n)); });
## [1] TRUE
А вот еще один пример создания списка матриц 2х3, сформированных с первыми тремя буквами:
allmatrices(letters[1:3],2L,3L);
## [[1]]
## [,1] [,2] [,3]
## [1,] "a" "a" "a"
## [2,] "a" "a" "a"
##
## [[2]]
## [,1] [,2] [,3]
## [1,] "b" "a" "a"
## [2,] "a" "a" "a"
##
## [[3]]
## [,1] [,2] [,3]
## [1,] "c" "a" "a"
## [2,] "a" "a" "a"
##
## [[4]]
## [,1] [,2] [,3]
## [1,] "a" "a" "a"
## [2,] "b" "a" "a"
##
## [[5]]
## [,1] [,2] [,3]
## [1,] "b" "a" "a"
## [2,] "b" "a" "a"
##
## [[6]]
## [,1] [,2] [,3]
## [1,] "c" "a" "a"
## [2,] "b" "a" "a"
##
## [[7]]
## [,1] [,2] [,3]
## [1,] "a" "a" "a"
## [2,] "c" "a" "a"
##
## [[8]]
## [,1] [,2] [,3]
## [1,] "b" "a" "a"
## [2,] "c" "a" "a"
##
## [[9]]
## [,1] [,2] [,3]
## [1,] "c" "a" "a"
## [2,] "c" "a" "a"
##
## [[10]]
## [,1] [,2] [,3]
## [1,] "a" "b" "a"
## [2,] "a" "a" "a"
##
## [[11]]
## [,1] [,2] [,3]
## [1,] "b" "b" "a"
## [2,] "a" "a" "a"
##
## ... snip ...
##
## [[719]]
## [,1] [,2] [,3]
## [1,] "b" "b" "c"
## [2,] "c" "c" "c"
##
## [[720]]
## [,1] [,2] [,3]
## [1,] "c" "b" "c"
## [2,] "c" "c" "c"
##
## [[721]]
## [,1] [,2] [,3]
## [1,] "a" "c" "c"
## [2,] "a" "c" "c"
##
## [[722]]
## [,1] [,2] [,3]
## [1,] "b" "c" "c"
## [2,] "a" "c" "c"
##
## [[723]]
## [,1] [,2] [,3]
## [1,] "c" "c" "c"
## [2,] "a" "c" "c"
##
## [[724]]
## [,1] [,2] [,3]
## [1,] "a" "c" "c"
## [2,] "b" "c" "c"
##
## [[725]]
## [,1] [,2] [,3]
## [1,] "b" "c" "c"
## [2,] "b" "c" "c"
##
## [[726]]
## [,1] [,2] [,3]
## [1,] "c" "c" "c"
## [2,] "b" "c" "c"
##
## [[727]]
## [,1] [,2] [,3]
## [1,] "a" "c" "c"
## [2,] "c" "c" "c"
##
## [[728]]
## [,1] [,2] [,3]
## [1,] "b" "c" "c"
## [2,] "c" "c" "c"
##
## [[729]]
## [,1] [,2] [,3]
## [1,] "c" "c" "c"
## [2,] "c" "c" "c"
Как вы можете видеть, этот алгоритм шаров из-под контроля очень быстро. Быть осторожен!
В дополнение к параметризации значений ячеек и размеров, я также передать VARIADIC аргументы в matrix()
вызовов, обеспечивая немного больше гибкости. Так, например, вы можете заполнить матрицы byrow
, а не по столбцам, и передать имена измерений, если вы хотите:
allmatrices(0:1,2L,2L,byrow=T,dimnames=list(letters[3:4],letters[1:2]));
## [[1]]
## a b
## c 0 0
## d 0 0
##
## [[2]]
## a b
## c 1 0
## d 0 0
##
## [[3]]
## a b
## c 0 1
## d 0 0
##
## [[4]]
## a b
## c 1 1
## d 0 0
##
## [[5]]
## a b
## c 0 0
## d 1 0
##
## [[6]]
## a b
## c 1 0
## d 1 0
##
## [[7]]
## a b
## c 0 1
## d 1 0
##
## [[8]]
## a b
## c 1 1
## d 1 0
##
## [[9]]
## a b
## c 0 0
## d 0 1
##
## [[10]]
## a b
## c 1 0
## d 0 1
##
## [[11]]
## a b
## c 0 1
## d 0 1
##
## [[12]]
## a b
## c 1 1
## d 0 1
##
## [[13]]
## a b
## c 0 0
## d 1 1
##
## [[14]]
## a b
## c 1 0
## d 1 1
##
## [[15]]
## a b
## c 0 1
## d 1 1
##
## [[16]]
## a b
## c 1 1
## d 1 1
тестирование производительности:
library(microbenchmark);
bgoldst <- function() allmatrices(0:1,2L,2L);
alexis <- function() { n <- 2; lapply(0:(((n*n)^2)-1),function(i) matrix(as.integer(head(intToBits(i),n*n)),n,n)); };
identical(bgoldst(),alexis());
## [1] TRUE
microbenchmark(bgoldst(),alexis(),times=1000L);
## Unit: microseconds
## expr min lq mean median uq max neval
## bgoldst() 62.865 70.136 80.15788 73.130 77.4060 1029.362 1000
## alexis() 187.741 205.702 229.48292 217.677 226.8705 1261.150 1000
Вполне вероятно
intToBits()
/
as.integer()
изменение это стоимость @ alexis_laz's решение немного скорость.
Редактировать: Хорошо сыграл, @alexis_laz! Вы выиграли в этом раунде:
alexis <- function() { n <- 2; lapply(0:(((n*n)^2)-1),function(i) matrix(as.integer(intToBits(i)[seq_len(n*n)]),n,n)); };
identical(bgoldst(),alexis());
## [1] TRUE
microbenchmark(bgoldst(),alexis(),times=1000L);
## Unit: microseconds
## expr min lq mean median uq max neval
## bgoldst() 64.148 70.136 77.98883 72.702 77.4055 1093.083 1000
## alexis() 48.325 54.313 63.70390 56.878 61.1550 3271.121 1000
Какая максимальная матрица вы интересуете? – Dave2e
Непонятно, что вы пытаетесь сделать и что такое вход, но вы можете найти полезный 'n = 2; lapply (0: (((n * n)^2) - 1), function (i) matrix (as.integer (head (intToBits (i), n * n)), n, n)) ' –
@alexis_laz это именно то, что я хотел сделать, большое спасибо. – Taldakus