【问题标题】:all combinations of n numbersn 个数的所有组合
【发布时间】:2014-06-12 03:41:20
【问题描述】:

我想生成 n 数字的所有唯一组合,无需替换。例如n = 4,则此处显示gamma(4+1) 组合:

combos4 <- read.table(text='

        x1  x2  x3  x4
         1   2   3   4
         1   2   4   3
         1   3   2   4
         1   3   4   2
         1   4   2   3
         1   4   3   2

         2   1   3   4
         2   1   4   3
         2   3   1   4
         2   3   4   1
         2   4   1   3
         2   4   3   1

         3   1   2   4
         3   1   4   2
         3   2   1   4
         3   2   4   1
         3   4   1   2
         3   4   2   1

         4   1   2   3
         4   1   3   2
         4   2   1   3
         4   2   3   1
         4   3   1   2
         4   3   2   1

', header = TRUE)

我可以使用以下代码获得这24种组合:

combos <- expand.grid(x1=1:4, x2=1:4, x3=1:4, x4=1:4)

my.combos <- combos[apply(combos,1,function(x) length(unique(x)) == ncol(combos)),]
my.combos

但是,我一直认为在 base R 中有一种更简单的方法。具体来说,我一直假设函数combn() 可以返回这些组合。但是,如果combn() 我现在可以意识到我不知道该怎么做。

expand.grid 方法似乎有点低效,尤其是当n 很大时。

在搜索互联网和 StackOverflow 时,我发现了几个使用 algorithm 标签的类似问题,并且在提供答案时发布的代码并不简单。抱歉,如果这是重复的,或者我遗漏了一些明显的东西。

【问题讨论】:

  • 您需要了解术语“组合”和“排列”之间的区别。组合被定义为集合成员,即没有顺序,而排列有顺序。
  • @BondedDust 是的。取点。我从来没有花足够的时间研究 Casella 和 Berger。我很懒惰,认为“独特的组合”就足够了。
  • 我并没有真正批评你的问题,因为你的例子清楚地表明了你想要什么。而是试图澄清有效的搜索策略可能是什么。
  • @BondedDust 我很感激。我喜欢学习,并感谢人们花时间指出我可以改进的方法。

标签: r combinations


【解决方案1】:

combinat 包有一个permn 函数

library(combinat)
permn(1:4)

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

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

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

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

[[5]]
[1] 4 1 3 2

[[6]]
[1] 1 4 3 2

[[7]]
[1] 1 3 4 2

[[8]]
[1] 1 3 2 4

[[9]]
[1] 3 1 2 4

[[10]]
[1] 3 1 4 2

[[11]]
[1] 3 4 1 2

[[12]]
[1] 4 3 1 2

[[13]]
[1] 4 3 2 1

[[14]]
[1] 3 4 2 1

[[15]]
[1] 3 2 4 1

[[16]]
[1] 3 2 1 4

[[17]]
[1] 2 3 1 4

[[18]]
[1] 2 3 4 1

[[19]]
[1] 2 4 3 1

[[20]]
[1] 4 2 3 1

[[21]]
[1] 4 2 1 3

[[22]]
[1] 2 4 1 3

[[23]]
[1] 2 1 4 3

[[24]]
[1] 2 1 3 4

【讨论】:

    【解决方案2】:

    gtools 有一个 permutations 函数可能会有所帮助:

    library(gtools)
    permutations(4,4,1:4)
    ##       [,1] [,2] [,3] [,4]
    ##  [1,]    1    2    3    4
    ##  [2,]    1    2    4    3
    ##  [3,]    1    3    2    4
    ##  [4,]    1    3    4    2
    ##  [5,]    1    4    2    3
    ##  [6,]    1    4    3    2
    ##  [7,]    2    1    3    4
    ##  [8,]    2    1    4    3
    ##  [9,]    2    3    1    4
    ## [10,]    2    3    4    1
    ## [11,]    2    4    1    3
    ## [12,]    2    4    3    1
    ## [13,]    3    1    2    4
    ## [14,]    3    1    4    2
    ## [15,]    3    2    1    4
    ## [16,]    3    2    4    1
    ## [17,]    3    4    1    2
    ## [18,]    3    4    2    1
    ## [19,]    4    1    2    3
    ## [20,]    4    1    3    2
    ## [21,]    4    2    1    3
    ## [22,]    4    2    3    1
    ## [23,]    4    3    1    2
    ## [24,]    4    3    2    1
    

    而且运行速度非常快:

       user  system elapsed 
      0.001   0.000   0.000 
    

    【讨论】:

      【解决方案3】:

      还有iterpc包。

      > I = iterpc(4, ordered=TRUE)
      > getall(I)
            [,1] [,2] [,3] [,4]
       [1,]    1    2    3    4
       [2,]    1    2    4    3
       [3,]    1    3    2    4
       [4,]    1    3    4    2
       [5,]    1    4    2    3
       [6,]    1    4    3    2
       [7,]    2    1    3    4
       [8,]    2    1    4    3
       [9,]    2    3    1    4
      [10,]    2    3    4    1
      ...
      

      你也可以反复做

      > getnext(I)
      [1] 1 2 3 4
      > getnext(I)
      [1] 1 2 4 3
      > getnext(I)
      [1] 1 3 2 4
      > getnext(I)
      [1] 1 3 4 2
      

      【讨论】:

        猜你喜欢
        • 2015-04-05
        • 1970-01-01
        • 1970-01-01
        • 2013-05-09
        • 2014-11-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多