Я могу ответить на весь вопрос, но это займет немного больше времени. Это должно дать вам ответ на вопрос.
В пакете 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