【问题标题】:Generate permutations of specific length with repetition in R?在R中重复生成特定长度的排列?
【发布时间】:2019-04-30 01:38:28
【问题描述】:

我有一个单词列表,我需要通过重复生成所有排列。必须指定排列的长度。单词列表很大(即 30 个单词),所以我的功能也需要高效.. 示例:

wordsList = c("alice", "moon", "walks", "mars", "sings", "guitar", "bravo")

鉴于每个排列必须恰好有 3 个单词,我需要生成所有排列。那将是["alice", "moon", "walks"]["alice", "walks", "moon"]["moon", "alice", "walks"]

【问题讨论】:

  • 当我提供一个大列表(即 3000 个单词列表,需要生成 15 个单词的组合)时,我的计算机挂起。知道如何分发或减少对 RAM 的依赖吗?
  • 生成那么多排列是不可行的。这超过了10^52 的总排列 (prod(3000:2986) = 1.38546e+52)。
  • 你有["alice", "moon", "walks"] 连续两次......你的意思是["alice", "moon", "walks"]["walks", "alice", "moon"]["moon", "alice", "walks"]
  • @JosephWood 确实有重复。我现在已经修好了。关于组合的数量,我认为我需要重新考虑。然而,我至少能做的是从 2100 个单词的列表中组合 11 个单词,我相信使用一些云硬件是可行的。主要问题是我不知道如何分配/并行化负载。
  • 看起来我遇到了一些错误,例如 cannot allocate vector of size 483342.8 Gb 480TB 的 RAM 实在是太疯狂了......而且我很确定我没有完成最后一次迭代

标签: r permutation


【解决方案1】:

有几个软件包可以完全满足您的需求。让我们从经典的gtools 开始。此外,从 OP 提供的示例来看,我们正在寻找没有重复的排列,而不是有重复的组合。

wordsList <- c("alice", "moon", "walks", "mars", "sings", "guitar", "bravo")

library(gtools)
attempt1 <- permutations(length(wordsList), 3, wordsList)
head(attempt1)
        [,1]    [,2]     [,3]    
[1,] "alice" "bravo"  "guitar"
[2,] "alice" "bravo"  "mars"  
[3,] "alice" "bravo"  "moon"  
[4,] "alice" "bravo"  "sings" 
[5,] "alice" "bravo"  "walks" 
[6,] "alice" "guitar" "bravo"

然后是iterpc

library(iterpc)
attempt2 <- getall(iterpc(length(wordsList), 3, labels = wordsList, ordered = TRUE))
head(attempt2)
        [,1]    [,2]    [,3]    
[1,] "alice" "moon"  "walks" 
[2,] "alice" "moon"  "mars"  
[3,] "alice" "moon"  "sings" 
[4,] "alice" "moon"  "guitar"
[5,] "alice" "moon"  "bravo" 
[6,] "alice" "walks" "moon"

最后,RcppAlgos(我是其作者)

library(RcppAlgos)
attempt3 <- permuteGeneral(wordsList, 3)
head(attempt3)
        [,1]     [,2]     [,3]    
[1,] "alice"  "bravo"  "guitar"
[2,] "bravo"  "alice"  "guitar"
[3,] "guitar" "alice"  "bravo" 
[4,] "alice"  "guitar" "bravo" 
[5,] "bravo"  "guitar" "alice" 
[6,] "guitar" "bravo"  "alice"

它们都相当有效并且产生相似的结果(不同的顺序)

identical(attempt1[do.call(order,as.data.frame(attempt1)),],
          attempt3[do.call(order,as.data.frame(attempt3)),])
[1] TRUE

identical(attempt1[do.call(order,as.data.frame(attempt1)),],
          attempt2[do.call(order,as.data.frame(attempt2)),])
[1] TRUE

如果你真的想要重复排列,每个函数都提供一个参数来执行该函数。

由于 OP 正在使用超过 3000 个单词的 wordsList,并且正在寻找一次选择 15 个的所有排列,因此上述方法将失败。有一些替代方案,来自iterpcRcppAlgos

使用iterpc,您可以使用函数getnext 并产生连续排列。我怀疑您是否能够在合理的时间内将它们全部生成或将它们存储在一个位置(即假设每个单元占用 8 个字节,10^52 * 15 * 8/(2^80) &gt; 10^29 YB 是的......那些是yobibytes......解释:“大量数据”)。

使用RcppAlgos,您可以利用rowCap 参数输出特定数量的排列,最多为2^31 - 1。例如:

permuteGeneral(wordsList, 3, upper = 5)
        [,1]     [,2]     [,3]    
[1,] "alice"  "bravo"  "guitar"
[2,] "bravo"  "alice"  "guitar"
[3,] "guitar" "alice"  "bravo" 
[4,] "alice"  "guitar" "bravo" 
[5,] "bravo"  "guitar" "alice"

【讨论】:

  • 还有来自combinat 包的permn。可能还有其他提供此功能的软件包我将(无意中)放弃。
  • 看起来 OP 想要 combinationsrepetitioniterpc 是我所知道的唯一一个能够生成替换组合的包(假设它是 OP 想要的)。
  • @RandyLai ,gtoolsRcppAlgos 都能够生成带有重复的组合。对于gtools,设置combination 函数的第五个参数repeats.allowed 会切换此功能,对于RcppAlgos,第三个参数repetition 的作用相同。请参阅文档 herehere
  • @RandyLai ,另外,如果您查看 OP 请求的输出,他们显然对什么是组合与排列感到困惑。 OP 说 “我需要生成所有组合....” 然后继续列出 3 个相同的组合。如您所知,顺序与组合无关,但与排列无关。任何人,我真的iterpc
  • @RandyLai,我的意思是“我真的喜欢 iterpc”。
【解决方案2】:

您可以使用 utils 包中的函数 combn

wordsList = c("alice", "moon", "walks", "mars", "sings", "guitar", "bravo")
combn(wordsList, 3)

这给出了我不想在这里重现的长输出。您也可以将输入作为一个因素,这可能有助于提高速度。

【讨论】:

  • 不需要调用library(utils),因为它是一个预加载的基础包。
【解决方案3】:

为了真正生成组合重复,Joseph Wood 的解决方案是关于没有重复的排列。 (编辑:虽然 OP 用重复写了组合,但他可能意味着排列!?见 cmets)

library(iterpc)
wordsList = c("alice", "moon", "walks", "mars", "sings", "guitar", "bravo")
getall(iterpc(length(wordsList), 3, labels = wordsList, replace = TRUE))
#>       [,1]     [,2]     [,3]    
#>  [1,] "alice"  "alice"  "alice" 
#>  [2,] "alice"  "alice"  "moon"  
#>  [3,] "alice"  "alice"  "walks" 
#>  [4,] "alice"  "alice"  "mars"  
#>  [5,] "alice"  "alice"  "sings" 
#>  [6,] "alice"  "alice"  "guitar"
#>  [7,] "alice"  "alice"  "bravo" 
#>  [8,] "alice"  "moon"   "moon"  
#>  [9,] "alice"  "moon"   "walks" 
..
..

【讨论】:

  • 这不是 OP 所要求的,尽管标题说 "...combinations with repeat..."。请参阅 OP 问题的 cmets 并检查他请求的输出(这些是排列,而不是组合)。此外,也许你已经有一段时间没有使用gtools,但它完全能够生成重复组合(参见here)。
  • 哎,你对 gtools 的看法是对的,我错过了。我想只有 OP 知道他想要什么。但是您绝对正确,他的示例看起来更像是排列而不是组合。
猜你喜欢
  • 1970-01-01
  • 2014-08-01
  • 1970-01-01
  • 2022-08-14
  • 1970-01-01
  • 1970-01-01
  • 2020-03-24
  • 2012-02-12
  • 1970-01-01
相关资源
最近更新 更多