我想快速生成离散的随机数,其中我有一个已知的CDF。基本上,算法是:
cdf
u
u < cdf[1]
选择1 u < cdf[2]
选择2 u < cdf[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))
答案 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提到的findInterval
或cut
或更好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)