2016-04-05 2 views
0

Я полностью новичок в языке R, и было бы неплохо получить некоторые подсказки от вас, ребята.Создать список (NxN) -серков со всей комбинацией 0s и 1s R-языка

Мне нужно создать список всех возможных сочетаний матриц, элементами которых будут 0s и 1s. Эти матрицы должны иметь одинаковое количество строк и столбцов.

Например, в случае матриц 2x2 будет 4^2 = 16 возможностей.

+0

Какая максимальная матрица вы интересуете? – Dave2e

+5

Непонятно, что вы пытаетесь сделать и что такое вход, но вы можете найти полезный 'n = 2; lapply (0: (((n * n)^2) - 1), function (i) matrix (as.integer (head (intToBits (i), n * n)), n, n)) ' –

+0

@alexis_laz это именно то, что я хотел сделать, большое спасибо. – Taldakus

ответ

3

Ваш вопрос вдохновил меня попробовать написать обобщенную функцию, которая может генерировать список всех матриц размерности 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 
+1

(только боковое примечание, вместо '' '' '' '' ', кажется, немного ускоряет его) –