2017-02-21 125 views
4

我想知道如何使用「基本操作」爲隨機變量建模。我知道的唯一隨機函數,至少對於C來說,是rand(),以及用於播種的srand。可能存在某些在線的軟件包,但可以說我想自己實現它。我不知道是否還有其他非常常見的隨機函數,但如果不是,只需堅持使用rand()和C語言。如何模擬隨機變量?

rand()允許我從0RAND_MAX僞隨機生成int。然後我可以使用mod在某個範圍內獲得int。我可以下mod 2選擇一個標誌並獲得負數。我也可以使用rand()/RAND_MAX來模擬間隔(0,1)中的值,並將其轉換爲Uniform(a,b)

但是我不確定的是,如果我可以擴展它來模擬任何概率分佈,以及在什麼時候我必須擔心精度,特別是在處理無窮大和無理概率時。此外,這種方法非常粗糙,所以我想知道更多使用基本工具的標準方法(如果有的話)。

一個簡單的例子:

我有隨機變量X使得Pr(X = 1)=1/piPr(X=0)=1-1/pi。由於pi不合理,因此我會近似得到1/pirand()的概率,並選擇X=1,如果我從0獲得intRound(RAND_MAX*1/pi)。所以這是近似兩次,一次爲pi,另一次爲四捨五入。

有沒有更好的方法?人們會怎樣去模擬一些更復雜的事情,如間隔(0,infinity)上的連續隨機變量,或者一個離散的隨機變量,它們在可數無限集合上具有無理概率。我的方法仍然有效嗎?還是我不得不擔心舍入錯誤?

編輯:另外如何僞隨機性而不是隨機性的0​​改變的事情,我將如何解釋這些變化?

+1

*「我可以使用mod在一定範圍內獲得int。」*不可以。你必須劃分,而不是使用mod,因爲你只會使用較低的位,而這些位較少隨機。 – spectras

+2

@spectras無法保證'rand'的質量。因此,不確定低位或高位是否「更隨機」。事實是,如果你需要任何種類的真正的隨機分配,「蘭特」是一個不行。哦,除非輸入範圍是除數的整數倍,否則div和mod都不適用。 – Olaf

+3

我覺得這個問題或多或少需要一個演講作爲答案。這並沒有錯,並且已經有這樣的講座史詩般的案例被傳遞,但它也(從字面上)要求很多。 :) – unwind

回答

7

然後我就可以使用國防部在一定範圍內

沒有得到一個int,你不能。用骰子嘗試。你需要一個介於1和5之間的數字。所以你採取滾動模5(種類,它實際上是((roll-1)%5)+1)。這會將1映射到1,2到2等,5到5和6到1.您現在有1倍於其他任何卷的可能性的兩倍。

這樣做的正確方法是找到距離範圍更近的2的最近冪,掩蓋2以上的隨機數的位,然後檢查是否在範圍內。如果你不在範圍內,再試一次(可能會永久循環,實際上平均重試次數小於2)。這假定你的隨機數是一串比特而不是別的。對於像樣的發電機這通常是一個安全的假設。

我還可以做蘭特()/ RAND_MAX到值在區間(0,1)

無不是模型,您可以。這不是浮點數的工作方式。這產生了一個可怕的分佈。

要麼是整數中的位數小於尾數中的位數,那麼您只會得到一堆您無法生成的浮點數。或者整數中的位數大於尾數中的位數,然後在分割之前將整數轉換爲浮點數時會截斷整數,並且會更頻繁地生成某些數字。

在區間(0,1)中,並將其移到模型Uniform(a,b)。

這使事情變得更糟。首先你在一個方向丟失比特,然後你在另一個方向丟失比特。

實際上在任意範圍內生成均勻分佈的浮點數比看起來要困難。

我已經做了一些實驗,幾年前這出自己,學習浮點內部在這個過程中,我已經寫了一些代碼有很多與推理在這裏評論:https://github.com/art4711/random-double

總之,在任意範圍內生成隨機浮點數:找到範圍中較大的絕對值。這是開始,範圍的另一端是結束。找出從開始到結束的下一個可表示數字。從開始減去下一個數字,即成爲步驟。計算開始和結束之間存在多少步驟。生成一個介於0和步數之間的均勻分佈的隨機數。開始+步驟*隨機數是答案。另外,由於浮點運算的原因,這可能不是你正在尋找的。所有可能的浮點值絕對不可能使用此方法生成(除非是非常特殊的情況)。但是這種方法保證了每個可能的值都是相同的。

請注意,您的錯誤觀念非常普遍。幾乎每個人都會做這些事情。該行業的隨機數字不是隨機的。計算機科學中的隨機詞幾乎意味着「可預測,可重複,容易破解和可利用,很可能分佈不均」。不要讓我開始關注標準庫中「隨機」數字生成器的質量。如果你圍繞我的github東西進行挖掘,你會發現一個關於這個的長篇README咆哮的Go包。

我不打算回答你的問題的其餘部分,這些位需要一兩本書。

+0

任何好的參考?謝謝。 – domoremath

+0

@domoremath並非如此。這僅僅是我多年來編寫代碼並與加密人(那些癡迷於好隨機數的人)聯繫在一起的知識。起點是認識到,僅僅因爲我們使用運算符'+',''','*'和'/'並不意味着它們在真正的數學中表現得如此。尤其是沒有浮點。其餘的只是閱讀標準和文檔,看看實際情況如何。 – Art