第一种算法严重失败有两个原因:
取的底值可以大大减小它。的确,当b − a < n时,它将为零,为您提供了一个值都相同的集合!(a − b )/ nb − a < n
当您不发言时,结果值分布得太均匀。 例如,在 iid均匀变量的任何简单随机样本中(例如和),存在机会最大将不在到的上限区间内。使用算法1,最大值有机会在该间隔内。在某些方面,这种超均匀性是好的,但是总的来说,这是一个可怕的错误,因为(a)许多统计信息将被破坏,但(b)很难确定原因。一个= 0 b = 1 (1 - 1 / Ñ )ñ ≈ 1 / Ë ≈ 37 %1 - 1 / ñ 1 100 %ña = 0b = 1(1 − 1 / n )ñ≈ 1 / Ë ≈ 37 %1 − 1 / n1个100 %
如果要避免排序,请生成独立的指数分布变量。用它们的和除以将它们的累积和标准化为范围。删除最大值(始终为)。重新缩放到范围(a ,b )。(0 ,1 )1n + 1(0 ,1 )1个(a ,b )
显示了所有三种算法的直方图。(每个图描绘了独立的集合的累积结果,每组n = 100个值。)算法1的直方图中缺少任何可见的变化就表明存在该问题。其他两种算法的变化正是您所期望的-以及您需要从随机数生成器获得的变化。1000n = 100
有关模拟独立均匀变量的更多(有趣的)方法,请参见使用正态分布的绘图来模拟均匀分布的绘图。
这是R
产生图形的代码。
b <- 1
a <- 0
n <- 100
n.iter <- 1e3
offset <- (b-a)/n
as <- seq(a, by=offset, length.out=n)
sim.1 <- matrix(runif(n.iter*n, as, as+offset), nrow=n)
sim.2 <- apply(matrix(runif(n.iter*n, a, b), nrow=n), 2, sort)
sim.3 <- apply(matrix(rexp(n.iter*(n+1)), nrow=n+1), 2, function(x) {
a + (b-a) * cumsum(x)[-(n+1)] / sum(x)
})
par(mfrow=c(1,3))
hist(sim.1, main="Algorithm 1")
hist(sim.2, main="Algorithm 2")
hist(sim.3, main="Exponential")
R
。为了在均匀间隔[ a ,b ]上生成个n个随机数的数组,以下代码起作用:。rand_array <- replicate(k, sort(runif(n, a, b))