給定一個像[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
這樣的數組,我想獲得一個考慮位置的隨機值。如何更經常地從一開始返回對象的數組中取值?
我希望1
的出現的可能性大於10
。
是這樣的可能嗎?
給定一個像[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
這樣的數組,我想獲得一個考慮位置的隨機值。如何更經常地從一開始返回對象的數組中取值?
我希望1
的出現的可能性大於10
。
是這樣的可能嗎?
爲了簡單起見,我們假設一個數組arr = [x, y, z]
,我們將從中抽樣值。我們希望看到以下的x
,y
和z
相對頻率:
frequencies = [5, 2, 1]
預處理這些頻率來計算利潤率爲我們後續的骰子:
thresholds = frequencies.clone
1.upto(frequencies.count - 1).each { |i| thresholds[i] += thresholds[i - 1] }
讓我們總結起來。
max = frequencies.reduce :+
現在選擇一個隨機數
roll = 1 + rand max
index = thresholds.find_index { |x| roll <= x }
返回arr[index]
結果。總結:
def sample arr, frequencies
# assert arr.count == frequencies.count
thresholds = frequencies.clone
1.upto(frequencies.count - 1).each { |i| thresholds[i] += thresholds[i - 1] }
max = frequencies.reduce :+
roll = 1 + rand(max)
index = thresholds.find_index { |x| roll <= x }
arr[index]
end
讓我們看看它是如何工作的。
data = 80_000.times.map { sample [:x, :y, :z], [5, 2, 1] }
一種data
直方圖顯示sample
作品正如我們所預期的。
一個簡單的方法來實現這與對數概率選擇是模擬硬幣翻轉。生成一個隨機整數0和1,該數組的索引是您獲得的連續1的數量。使用這種方法,選擇2的機會是1的可能性爲1,3的可能性爲1/4,等等。您可以通過生成0到5之間的隨機數來稍微改變概率,並計算連續輪次數大於1,這使得數組中的每個數字可能會像之前那樣顯示。
解決此問題的更好和更一般的方法是使用別名方法。請參閱此問題的答案以獲取更多信息: Data structure for loaded dice?
def coin_toss(arr)
arr.detect{ rand(2) == 0 } || arr.last
end
a = (1..10).to_a
10.times{ print coin_toss(a), ' ' } #=> 1 1 1 9 1 5 4 1 1 3
這需要陣列,flips a coin的第一個元素,則返回元件並停止,如果是coinflip「尾料」;否則與下一個元素相同。如果它始終是「頭」,則返回最後一個元素。
'way'更大?多大?決定你想要什麼類型的分配。 – Dan 2012-01-06 23:30:23