,分佈是什麼樣的?當您在大多數語言中使用隨機(最小,最大)函數時,從傾斜的正態分佈生成隨機數
如果我想在20%的時間內產生一個範圍的數字,而在80%的時間內產生另一個範圍的數字,我該如何產生一系列隨機數?
前)我應該得到隨機頻率,但「1」的頻率必須高於20%左右比「0」
,分佈是什麼樣的?當您在大多數語言中使用隨機(最小,最大)函數時,從傾斜的正態分佈生成隨機數
如果我想在20%的時間內產生一個範圍的數字,而在80%的時間內產生另一個範圍的數字,我該如何產生一系列隨機數?
前)我應該得到隨機頻率,但「1」的頻率必須高於20%左右比「0」
大多數計算機語言有均勻分佈的(僞)隨機整數頻率發電機。所以每個整數都是可能的。
對於您的示例,假設您希望「1」55%的時間和「0」45%的時間。
要使這些頻率不相等,請嘗試生成1到100之間的隨機數。如果生成的數字是1到55,則輸出「1」;否則輸出「0」。
大多數僞隨機發生器內置的編程語言產生均勻分佈,即該範圍內的每個值具有被製造爲在範圍內的任何其他值的概率相同。事實上,在某些情況下,這個要求是語言標準的一部分。諸如Python或R等一些語言支持各種通用發行版。
如果語言不支持它,您必須使用數學技巧來生成其他分佈(例如統一分佈的正態分佈),或者您可以查找執行此功能的第三方庫。
你的問題似乎簡單得多然而,由於隨機變量是離散(及其簡單的類型,即二進制的)。這些技巧是從均勻分佈產生一個隨機數,在一個給定的範圍內,比如說0到999,並且按照與每個值相關的比例來分割這個範圍,在這種情況下,這將是類似的:
If (RandomNumber) < 200 // 20%
RandomVariable = 0
Else // 80%
RandomVariable = 1
該邏輯當然可以應用於n個離散變量。
對於大多數語言,生成的隨機數可能取決於該語言中的算法,或者根據幾個因素(如時間,處理器,種子編號)隨機生成。
分佈不正常。實際上,如果函數返回5個整數,則所有5個整數在下一個函數調用中都有相當的機會出現。這也被稱爲統一分配。
所以說,如果你想產生一個數字(比如7)的20%的時間,而對於80%的時間另一個號碼(比如13),你可以做一個這樣的數組:
var arr = [7,13,13,13,13];
var picked = arr[Math.floor(Math.random()*arr.length)] ;
// since Math.random() returns a float from 0.0 to 1.0
因此,7有20%的機會出現,13有80%的機會。
這是一個可行的方法:
ranges = [(10..15), (20..30)]
selector = [0, 0, 1,1,1,1,1,1,1,1] # 80:20 distribution array
# now select a range randomly
random_within_range(ranges(selector[random(10)]))
def random_within_range range
rand (range.last - range.begin - (range.exclude_end? ? 1 : 0)) + range.begin
end
如何
var oneFreq = 80.0/100.0;
var output = 0;
if (Math.random() > oneFreq)
output = 1;
,或者,如果你需要的值的20%爲0和100,以及80%至100之間和200.
var oneFreq = 80.0/100.0;
var oneRange = 100;
var zeroRange = 100;
var output = Math.random();
if (output > oneFreq)
output = zeroRange + Math.floor(oneRange * (output - oneFreq));
else
output = Math.floor(zeroRange * output);
你的問題與你的例子有點不同。所以我會回答這兩個問題,你可以找出你真正需要的答案。
1)你的榜樣(我不知道紅寶石或Java,所以大家多多包涵)
2)從與歪斜
看看this lecture如果你想要一個良好的數學理解。
在紅寶石我會做這樣的:
class DistributedRandom
def initialize(left, right = nil)
if right
@distribution = [0] * left + [1] * right
else
@distribution = left
end
end
def get
@distribution[rand @distribution.length]
end
end
運行測試以80:20分配:
test = [0,0]
rnd = DistributedRandom.new 80, 20 # 80:20 distribution
10000.times { test[rnd.get] += 1 }; puts "Test 1", test
與右側的20%以上分配運行測試:
test = [0,0]
rnd = DistributedRandom.new 100, 120 # +20% distribution
10000.times { test[rnd.get] += 1 }; puts "Test 2", test
使用自定義分佈與三角函數運行測試超過91個離散值,出但是把不適合非常順利進入之前的測試:
test = [0,0]
rnd = DistributedRandom.new((0..90).map {|x| Math.sin(Math::PI * x/180.0)})
10000.times { test[rnd.get] += 1 }; puts "Test 3", test
像別人說什麼,對大多數語言的僞隨機數發生器實現了(0,1)的均勻分佈。 如果你有1 p的概率兩個響應類別(0,1),你有一個伯努利分佈,可與
# returns 1 with p probability and 0 with (1-p) probability
def bernoulli(p)
rand()<p ? 1:0;
end
這麼簡單效仿。 偏斜的正態分佈是一個完全不同的野獸,由正態分佈的pdf和cdf的'聯合'產生歪斜。你可以閱讀Azzalini的作品here。利用創業板發行,可以生成概率密度函數,與
# require 'distribution'
def sn_pdf(x,alpha)
sp = 2*Distribution::Normal.pdf(x)*Distribution::Normal.cdf(x*alpha)
end
獲取的CDF是困難的,因爲沒有解析解,所以你應該整合。 要從傾斜的法線中獲得隨機數,您可以使用acceptation-rejection算法。
PS:「正常」分佈與統一分佈不同。 – 2010-03-07 03:19:34