Random-Generation

如何有效地在區間內生成排序均勻分佈的值?

  • January 20, 2015

假設我想從區間生成一組隨機數(a, b)。生成的序列還應該具有已排序的屬性。我可以想到兩種方法來實現這一點。

n為要生成的序列的長度。

第一種算法:

Let `offset = floor((b - a) / n)`
for i = 1 up to n:
  generate a random number r_i from (a, a+offset)
  a = a + offset
  add r_i to the sequence r

第二種算法:

for i = 1 up to n:
   generate a random number s_i from (a, b)
   add s_i to the sequence s
sort(r)

我的問題是,算法 1 生成的序列是否與算法 2 生成的序列一樣好?

第一個算法嚴重失敗有兩個原因:

  1. 發言可以大幅度減少。確實,當,它將為零,為您提供一個值都相同的集合!
  2. 當您不發言時,結果值分佈過於均勻 例如,在任何簡單的隨機樣本中iid 統一變量(比如在和),有一個最大的可能不在上區間到. 對於算法 1,有一個最大值將在該區間內的機會。出於某些目的,這種超均勻性是好的,但總的來說,這是一個可怕的錯誤,因為 (a) 許多統計數據會被破壞,但 (b) 很難確定原因。
  3. 如果要避免排序,請改為生成獨立的指數分佈變量。將它們的累積總和標準化為範圍除以總和。刪除最大值(這將始終是)。重新縮放到範圍.

顯示了所有三種算法的直方圖。(每個描述的累積結果獨立組每個值。)算法 1 的直方圖中沒有任何可見的變化表明了那裡的問題。其他兩種算法的變化正是可以預期的——以及隨機數生成器所需要的。

有關模擬獨立均勻變量的更多(有趣)方法,請參閱使用正態分佈的繪圖模擬均勻分佈的繪圖

圖:直方圖

這是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")

引用自:https://stats.stackexchange.com/questions/134241

comments powered by Disqus

相關問答