Комбинации вектора с субвекторной длиной n - PullRequest
1 голос
/ 28 апреля 2020

Учитывая вектор 1:4 и длину последовательности 2, я хотел бы разделить вектор на «субвекторы», каждый из которых имеет длину 2, и сгенерировать матрицу всех возможных комбинаций этих субэлементов. -vectors.

Вывод будет выглядеть так:

     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    3    4    1    2

Другой пример. С вектором 1:8 и длиной субвектора 4, результат будет выглядеть следующим образом:

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,]    1    2    3    4    5    6    7    8
[2,]    5    6    7    8    1    2    3    4

С вектором 1:9 и длиной субвектора 3, результат будет выглядеть следующим образом:

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,]    1    2    3    4    5    6    7    8    9
[2,]    1    2    3    7    8    9    4    5    6
[3,]    4    5    6    1    2    3    7    8    9
[4,]    4    5    6    7    8    9    1    2    3
[5,]    7    8    9    4    5    6    1    2    3
[6,]    7    8    9    1    2    3    4    5    6

Дано, что длина вектора должна делиться на длину субвектора.

1 Ответ

2 голосов
/ 28 апреля 2020

Я могу ответить на весь вопрос, но это займет немного больше времени. Это должно дать вам ответ на вопрос.

В пакете combinat есть функция с именем permn, которая дает вам все перестановки вектора. Вы хотите этого, но не совсем. Что вам нужно, это перестановки всех блоков. Итак, в вашем первом примере у вас есть два блока длиной два, а во втором - три блока длиной три. Если мы посмотрим на первое и подумаем о порядке размещения блоков :

> library(combinat)
> numBlocks = 2
> permn(1:numBlocks)
[[1]]
[1] 1 2

[[2]]
[1] 2 1

Так что я надеюсь, что вы видите, что первая перестановка займет блоки b1 = c(1,2) и b2 = c(3,4) и упорядочите их c(b1,b2), а второй упорядочит их c(b2,b1).

Точно так же, если у вас было три блока, b1 = 1:3; b2 = 4:6; b3 = 7:9, тогда

permn(1:3)
[[1]]
[1] 1 2 3

[[2]]
[1] 1 3 2

[[3]]
[1] 3 1 2

[[4]]
[1] 3 2 1

[[5]]
[1] 2 3 1

[[6]]
[1] 2 1 3

даст вам порядок этих блоки. Более общее решение - выяснить, как перемещать блоки, но это не так сложно.

Обновление: Использование моего пакета multicool. Примечание ко-лексическое упорядочение (coolex) - это не тот порядок, который вы придумаете сами.

library(multicool)

combs = function(v, blockLength){
  if(length(v) %% blockLength != 0){
    stop("vector length must be divisible by blockLength")
  }

  numBlocks = length(v) / blockLength
  blockWise = matrix(v, nc = blockLength, byrow = TRUE)

  m = initMC(1:numBlocks)
  Perms = allPerm(m)

  t(apply(Perms, 1, function(p)as.vector(t(blockWise[p,]))))
}
> combs(1:4, 2)
     [,1] [,2] [,3] [,4]
[1,]    3    4    1    2
[2,]    1    2    3    4
> combs(1:9, 3)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,]    7    8    9    4    5    6    1    2    3
[2,]    1    2    3    7    8    9    4    5    6
[3,]    7    8    9    1    2    3    4    5    6
[4,]    4    5    6    7    8    9    1    2    3
[5,]    1    2    3    4    5    6    7    8    9
[6,]    4    5    6    1    2    3    7    8    9
...