【问题标题】:Generate permutations in sequential order - R按顺序生成排列 - R
【发布时间】:2019-05-08 16:19:50
【问题描述】:

我之前问过以下问题 Permutation of n bernoulli random variables in R

这个问题的答案很好用,只要n比较小(

此代码的目的是计算精确分布(因此是排列)和正态近似的 CDF 之间的差异。我随机生成一些数据,计算测试统计量,然后我需要通过将导致较小测试统计量值的所有排列相加除以排列总数来确定 CDF。

我的想法是一次只生成一个排列列表,注意它是否小于我的观察值,然后继续下一个,即遍历所有可能的排列,但我不能只拥有要循环遍历的所有排列的数据框,因为这会导致完全相同的大小和速度问题。

长话短说:我需要为 n 次伯努利试验生成所有可能的 1 和 0 排列,但我需要一次执行一次,以便生成所有这些排列,并且对于任意 n 次都不会多次生成.对于 n = 3, 2^3 = 8,我会先生成

000

计算我的测试统计量是否大于(1 或 0)然后生成

001

再次计算,然后生成

010

计算,然后生成

100

计算,然后生成

011

等到 111

我很满意这是一个超过 2^n 的循环,它在循环的每一步输出排列,但不会将它们全部保存在某个地方。另外,我不在乎它们的生成顺序,以上只是我手动操作时的列出方式。

此外,如果有任何方法可以加速以前的代码,那也会有所帮助。

【问题讨论】:

    标签: r performance permutation


    【解决方案1】:

    您的问题的一个很好的解决方案是迭代器。有一个名为arrangements 的包能够以迭代方式生成排列。观察:

    library(arrangements)
    
    # initialize iterator 
    iperm <- ipermutations(0:1, 3, replace = T)
    
    for (i in 1:(2^3)) {
        print(iperm$getnext())
    }
    
    [1] 0 0 0
    [1] 0 0 1
    .
    .
    .
    [1] 1 1 1
    

    用C写的,效率很高。您还可以像这样一次生成m 排列:

    iperm$getnext(m)
    

    这可以提高性能,因为下一个排列是由 C 中的 for 循环生成的,而不是 R 中的 for 循环。

    如果您确实需要提高性能,您可以使用 parallel 软件包。

    iperm <- ipermutations(0:1, 40, replace = T)
    
    parallel::mclapply(1:100, function(x) {
        myPerms <- iperm$getnext(10000)
        # do something
    }, mc.cores = parallel::detectCores() - 1)
    

    注意:所有代码都未经测试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-28
      • 2013-04-22
      • 1970-01-01
      • 2015-05-11
      • 2015-07-04
      相关资源
      最近更新 更多