有效地生成离散随机数

时间:2013-02-28 14:03:52

标签: r random memory-efficient

我想快速生成离散的随机数,其中我有一个已知的CDF。基本上,算法是:

  1. 构造CDF向量(从0开始并从1结束的递增向量)cdf
  2. 生成统一(0,1)随机数u
    • 如果u < cdf[1]选择1
    • 如果u < cdf[2]选择2
    • ,则为其他人
    • 如果u < cdf[3]选择3,则为其他人 * ...
  3. 示例

    首先生成一个cdf:

    cdf = cumsum(runif(10000, 0, 0.1))
    cdf = cdf/max(cdf)
    

    接下来生成N个统一随机数:

    N = 1000
    u = runif(N)
    

    现在对值进行采样:

    ##With some experimenting this seemed to be very quick
    ##However, with N = 100000 we run out of memory
    ##N = 10^6 would be a reasonable maximum to cope with
    colSums(sapply(u, ">", cdf))
    

3 个答案:

答案 0 :(得分:4)

如果您知道概率质量函数(如果您知道累积分布函数),则可以使用R的内置sample函数,您可以使用参数{定义离散事件的概率{ {1}}。

prob

答案 1 :(得分:3)

如何使用cut

N <- 1e6
u <- runif(N)
system.time(as.numeric(cut(u,cdf)))
   user  system elapsed 
   1.03    0.03    1.07 

head(table(as.numeric(cut(u,cdf))))

  1   2   3   4   5   6 
 51  95 165 172 148  75 

答案 2 :(得分:2)

如果您的可能值数量有限,那么您可以使用@Hemmo提到的findIntervalcut或更好sample

但是,如果你想从理论上变为无穷大的分布中生成数据(如几何,负二项式,泊松等),那么这里有一个算法可以工作(这也适用于有限数如果需要,可以使用值:

从你的均匀值向量开始,循环分配值从制服向量中减去它们,随机值是值为负的迭代。这是一个更容易看到的例子。这将从平均值为5的Poisson生成值(将dpois调用替换为您的计算值)并将其与使用逆CDF进行比较(在这种情况下,它更有效)。

i <- 0
tmp <- tmp2 <- runif(10000)
randvals <- rep(0, length(tmp) )

while( any(tmp > 0) ) {
    tmp <- tmp - dpois(i, 5)
    randvals <- randvals + (tmp > 0)
    i <- i + 1
}

randvals2 <- qpois( tmp2, 5 )

all.equal(randvals, randvals2)