【问题标题】:R: function that returns all the possible ordering of n elements?R:返回n个元素所有可能排序的函数?
【发布时间】:2015-03-17 19:53:37
【问题描述】:

在 R 中,是否有一个函数可以返回 n 个元素的所有可能排序? 我想要一个n!通过 n 矩阵,使得每一行包含 n 个元素的所有可能的排序索引。也就是说,如果 n = 3,我想要:

 1,2,3 
 1,3,2,
 2,1,3,
 2,3,1,
 3,1,2,
 3,2,1

我首先认为 expand.grid 可以完成这项工作,然后尝试:

n <- 3
expand.grid(rep(list(1:n),n))

   Var1 Var2 Var3
1     1    1    1
2     2    1    1
3     3    1    1
4     1    2    1
5     2    2    1
6     3    2    1
7     1    3    1
8     2    3    1
9     3    3    1
10    1    1    2
11    2    1    2
12    3    1    2
13    1    2    2
14    2    2    2
15    3    2    2
16    1    3    2
17    2    3    2
18    3    3    2
19    1    1    3
20    2    1    3
21    3    1    3
22    1    2    3
23    2    2    3
24    3    2    3
25    1    3    3
26    2    3    3
27    3    3    3

但这会返回 3^3 x 3 矩阵,每行可能包含重复值...

【问题讨论】:

    标签: r combinations combinatorics


    【解决方案1】:

    试试

    library(gtools)
    permutations(n,3)
    #     [,1] [,2] [,3]
    #[1,]    1    2    3
    #[2,]    1    3    2
    #[3,]    2    1    3
    #[4,]    2    3    1
    #[5,]    3    1    2
    #[6,]    3    2    1
    

    【讨论】:

      【解决方案2】:

      这里有一些选项:

      n = 3
      
      library(gtools)
      permutations(n,n)
      
      library(combinat)
      permn(1:n)
      
      library(multicool)
      m = initMC(1:n)
      allPerm(m)
      
      library(iterpc)
      I = iterpc(n, ordered = TRUE)
      getall(I)
      

      让我们做一些基准测试

      n=5
      I = iterpc(n, ordered = TRUE)
      m=initMC(1:n)
      
      library(microbenchmark)
      microbenchmark( permutations(n,n), permn(1:n), allPerm(m), getall(I) )
      
      # Unit: microseconds
      #               expr      min        lq    median        uq      max neval
      # permutations(n, n) 2781.110 2857.9100 2922.7635 2973.5835 4877.656   100
      #         permn(1:n) 3600.310 3664.0255 3722.6210 3772.4940 5475.748   100
      #         allPerm(m)  325.026  458.1460  503.6575  558.8390  719.835   100
      #          getall(I)  169.151  189.0615  245.5715  284.8245  472.937   100
      

      来自gtoolspermutations 和来自cobinatpermn 是用R 编写的,而另外两个是用C 编写的,所以速度要快得多。
      此外,multicool 提供了一种专门为多集排列而设计的算法。所以看来iterpc 是简单排列的更好选择:

      f1 <- function(n){
      m=initMC(1:n)
      allPerm(m)}
      
      f2 <- function(n){
      I = iterpc(n, ordered = TRUE)
      getall(I)}
      
      microbenchmark(f1(10),f2(10))
      
      # Unit: milliseconds
      #   expr       min        lq    median        uq       max neval
      # f1(10) 1143.8057 1216.4617 1322.2973 1335.5547 1383.8723   100
      # f2(10)  421.7535  457.3466  461.4995  551.4025  648.8821   100
      

      【讨论】:

      • 这里是iterpc的作者。实际上 iterpc 也能够处理多重集。 :)
      【解决方案3】:

      另一个包combinat,其中permn返回list,可以使用以下转换为matrix

      library(combinat)
      t(simplify2array(permn(1:3)))
      
      #     [,1] [,2] [,3]
      #[1,]    1    2    3
      #[2,]    1    3    2
      #[3,]    3    1    2
      #[4,]    3    2    1
      #[5,]    2    3    1
      #[6,]    2    1    3
      

      【讨论】:

      • do.call(rbind, perm(1:3))
      猜你喜欢
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-28
      • 2015-02-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多