2015-11-04 35 views
3

我正在編寫我的大學作業,它與分佈和隨機卷子有些相關。所以問題是:如何在Ruby中獲得具有給定離散分佈的隨機數。如何獲得一個隨機數在Ruby中給定的分佈式分佈

更具體地:在簡單的例子中包含正常離散分佈(0與P = 1/2; 1000,P = 1/2)可以寫這樣的功能:

def chooseNumber(a,b) 
    rval = Random.rand(0..1) 
    return a if rval == 0 
    return b 
end 

第一個問題:有沒有什麼方法可以使用本機Random類來編寫它?第二個問題:處理分佈問題的最好方法是什麼?(0 = P = 1/5; 2 = P = 2/5; 1000 = P = 2/5)或者更差(P = 0,33; 2與P = 0,49; 1000與P = 0,18)?

+0

http://stackoverflow.com/ q/8877249/125816 - 這是javascript,但你應該明白。 –

+1

查看[AliasTable](https://rubygems.org/gems/aliastable)gem以獲得高效的通用解決方案。 – pjs

+0

@pjs謝謝!這是應該解決的。 – ddnomad

回答

3

我會的東西是這樣的

def pick_with_distribution(distributions) 
    r = rand 
    distributions.detect{ |k, d| r -= d; r < 0 }.first 
end 

distributions = { 0 => 0.33, 2 => 0.49, 1000 => 0.18 } 
pick_with_distribution(distributions) 
#=> 0 

要檢查是否分佈是正確的,我運行10000次,這裏是結果:

10000.times.inject({}) do |h, _| 
    r = pick_with_distribution(distributions) 
    h[r] ||= 0 
    h[r] += 1 
    h 
end 
#=> {0=>3231, 1000=>1860, 2=>4909} 
+0

@NeilSlater是的,它甚至可以用O(1)進行一些預處理。當然。你可以用額外的內存和O(1)提取創建概率表。或者可以在預處理概率值之後在O(log(n))中使用二進制搜索。 – fl00r

+0

@NeilSlater對於少數幾種替代品來說,這種替代品的質量差不多。對於大量的結果,[別名表](https://en.wikipedia.org/wiki/Alias_method)在初始設置後具有恆定的時間行爲。 – pjs

+0

fl00r和@pjs謝謝你們倆:)你已經度過了我的一天 – ddnomad