вычислить всю перестановку с повторением списка R - PullRequest
0 голосов
/ 07 ноября 2018

у меня есть этот список векторов out:

[[1]]
[1] (1,5)(3)(4)(6)

[[2]]
[1] (3,6)(1)(4)(5)

[[3]]
[1] (3,4)(1)(5)(6)

[[4]]
[1] (3,5)(1)(4)(6)

[[5]]
[1] (4,6)(1)(3)(5)

[[5]]
[1] (4,5)(1)(3)(6)

[[6]]
[1] (5,6)(1)(3)(4)   

возьмем один элемент, например, out[[5]] (4,6)(1)(3)(5), я бы сгенерировал все перестановки элементов со всем возможным порядком, например:

{(4,6)(3)(1)(5)},{(3)(4,6)(5)(1)}...

Ответы [ 3 ]

0 голосов
/ 07 ноября 2018

Как насчет пакетов gtools

out <- list(
 c(1.5,3,4,6),
 c(3.6,1,4,5),
 c(3.4,1,5,6),
 c(3.5,1,4,6),
 c(4.6,1,3,5),
 c(4.5,1,3,6),
 c(5.6,1,3,4))


require(gtools)

allPerm <- function(x){

  return(permutations(length(x), length(x), x))
}
0 голосов
/ 07 ноября 2018

Я думаю, это то, что ищет ОП:

out <- list(c("(1,5)","(3)","(4)","(6)"), c("(3,6)","(1)","(4)","(5)"), 
            c("(3,4)","(1)","(5)","(6)"),c("(3,5)","(1)","(4)","(6)"), 
            c("(4,6)","(1)","(3)","(5)"), c("(4,5)","(1)","(3)","(6)"), 
            c("(5,6)","(1)","(3)","(4)"))

library(RcppAlgos)
myPerms <- lapply(out, function(x) {
    unlist(permuteGeneral(x, length(x), FUN = function(y) {
        paste0(c("{", y, "}"), collapse = "")
    }))
})

Мы используем permuteGeneral из RcppAlgos (я - автор), поскольку мы можем использовать аргумент FUN для передачи пользовательской функции, которая будет применяться к каждой перестановке (т.е. paste0(c("{", y, "}"), collapse = "")).

Вот вывод 5-го элемента:

myPerms[[5]]
[1] "{(4,6)(1)(3)(5)}" "{(4,6)(1)(5)(3)}" "{(4,6)(3)(1)(5)}"
[4] "{(4,6)(3)(5)(1)}" "{(4,6)(5)(1)(3)}" "{(4,6)(5)(3)(1)}"
[7] "{(1)(4,6)(3)(5)}" "{(1)(4,6)(5)(3)}" "{(1)(3)(4,6)(5)}"
[10] "{(1)(3)(5)(4,6)}" "{(1)(5)(4,6)(3)}" "{(1)(5)(3)(4,6)}"
[13] "{(3)(4,6)(1)(5)}" "{(3)(4,6)(5)(1)}" "{(3)(1)(4,6)(5)}"
[16] "{(3)(1)(5)(4,6)}" "{(3)(5)(4,6)(1)}" "{(3)(5)(1)(4,6)}"
[19] "{(5)(4,6)(1)(3)}" "{(5)(4,6)(3)(1)}" "{(5)(1)(4,6)(3)}"
[22] "{(5)(1)(3)(4,6)}" "{(5)(3)(4,6)(1)}" "{(5)(3)(1)(4,6)}"

Если вы действительно хотите перестановки с повторениями, просто установите repetition = TRUE в permuteGeneral. Конечно, если вы хотите более полезный вывод, мы можем вообще отказаться от пользовательского FUN.

UPDATE

Узнав больше о том, как ОП получил out выше, мы можем лучше решить проблему. Сначала мы узнаем, что OP использует listParts из библиотеки partitions. Глядя на исходный код у нас:

listParts
function (x) 
{
    f <- function(pp) {
        out <- split(seq_along(pp), pp)
        class(out) <- c(class(out), "equivalence")
        out
    }
    apply(setparts(x), 2, f)
}
<bytecode: 0x10d7b09f8>
<environment: namespace:partitions>

Мы можем изменить это, чтобы получить все перестановки:

permListParts <- function (x) 
{
    f <- function(pp) {
        out <- split(seq_along(pp), pp)
        myPerms <- perms(length(out))
        apply(myPerms, 2, function(x) {
            temp <- out[x]
            class(temp) <- c(class(temp), "equivalence")
            temp
        })
    }
    apply(setparts(x), 2, f)
}

Заметим, что мы идем против намерения listParts ... процитировать документацию:

"Обратите внимание, что (12) (3) (4) такое же разбиение, как, например, (3) (4) (21), поскольку отношение эквивалентности такое же."

Да ладно ... вот вывод для перестановок длины 3:

permListParts(3)
[[1]]
[[1]][[1]]
[1] (1,2,3)


[[2]]
[[2]][[1]]
[1] (1,3)(2)

[[2]][[2]]
[1] (2)(1,3)


[[3]]
[[3]][[1]]
[1] (1,2)(3)

[[3]][[2]]
[1] (3)(1,2)


[[4]]
[[4]][[1]]
[1] (2,3)(1)

[[4]][[2]]
[1] (1)(2,3)


[[5]]
[[5]][[1]]
[1] (1)(2)(3)

[[5]][[2]]
[1] (1)(3)(2)

[[5]][[3]]
[1] (2)(1)(3)

[[5]][[4]]
[1] (2)(3)(1)

[[5]][[5]]
[1] (3)(1)(2)

[[5]][[6]]
[1] (3)(2)(1)
0 голосов
/ 07 ноября 2018

Вы можете попробовать это:

test <- list(list(1,5),3,4,6)
combn(test,2)
> combn(test,2)
     [,1]   [,2]   [,3]   [,4] [,5] [,6]
[1,] List,2 List,2 List,2 3    3    4   
[2,] 3      4      6      4    6    6   

Это даст вам все возможные комбинации из 2 элементов из вашего списка. Если вы хотите сделать это для каждого элемента вашего основного списка, вы можете использовать for или lapply.

попробовать:

lapply(out, function(x) combn(x,2))
...