2014-03-13 175 views
3

我應該驗證我們實現Lua的隨機數生成器的能力。Lua,隨機是如何隨機的?

這是我想出了...

for i = 1,10000 do       -- I hope that's ten thousand 

X = math.random(0,9) 

if  X == 0 then This_Many_0 = This_Many_0 + 1 
elseif X == 1 then This_Many_1 = This_Many_1 + 1 
elseif X == 2 then This_Many_2 = This_Many_2 + 1 
elseif X == 3 then This_Many_3 = This_Many_3 + 1 
elseif X == 4 then This_Many_4 = This_Many_4 + 1 
elseif X == 5 then This_Many_5 = This_Many_5 + 1 
elseif X == 6 then This_Many_6 = This_Many_6 + 1 
elseif X == 7 then This_Many_7 = This_Many_7 + 1 
elseif X == 8 then This_Many_8 = This_Many_8 + 1 
elseif X == 9 then This_Many_9 = This_Many_9 + 1 

else    Bogus_Alert = True  -- Better not happen 

end          -- End the big if/elseif block 

The_Interim_Sum = The_Interim_Sum + X  -- Keep a running sum 

end          -- This is the i loop 

我然後打印結果,他們在這裏...

Running 
Number of times we got 0 ... 1019 
Number of times we got 1 ... 979 
Number of times we got 2 ... 954 
Number of times we got 3 ... 1006 
Number of times we got 4 ... 995 
Number of times we got 5 ... 999 
Number of times we got 6 ... 989 
Number of times we got 7 ... 1000 
Number of times we got 8 ... 1042 
Number of times we got 9 ... 1017 
The sum of the ten thousand random numbers was 45303 
The average of those numbers was 4.5303 
End 

這些跟隨我的預期;即平均值非常接近4.5,並且每個單獨數字的分佈接近一千。

更重要的是,用這樣的數字,我說的確的確如此,該生成器在製作真正非常隨機的一萬個隨機數方面做得非常好。

這裏有一個困惑的地方:我的老闆說如果機器真的在做它的工作,並真正給我們隨機數,那麼每個數字的分佈應該是均勻的;即在一萬次迭代中,我應該精確地得到每個數字的一​​千個數字。

我想這是基於這裏StackOverflow上一些其他的對話使用X = math.random(0,9)循環之前加入math.randomseed(os.time())。結果進一步關閉,而不是更接近。

我拿出math.randomseed(os.time())一行,再次運行測試,平均得到4.5007(這是我見過的最好的)。

那麼,我發現了什麼?什麼?沒有 ?隨機數發生器實際上是一個*僞*隨機數發生器?大家已經知道了。

我是否證明了這個僞隨機數發生器大約是隨機的,正如我們所期望的那樣?

我有理由害怕使用這些值嗎?我會按照常規拿球,並給他刻意的壞數字。全系列對於測試每個案例來說都太多了。我猜測,正確分佈的16K炮擊會讓我相信該芯片正確地處理(故意壞的)值。

(閱讀說明,我在多處理器系統上做V & V和我的Lua腳本是僞造的系統,我們不具備的地區之一的行爲呢。)

有沒有一種方法可以讓Lua在這種情況下使用math.random()函數生成每個數字中的一千個?

如果是這樣,那真的會是隨機的嗎?

+2

爲什麼你會想到一個真正的隨機分佈,產生每個數字的數量相等?雖然均勻分佈是最有可能的*特定的結果,但您看到它的可能性要遠遠低於看到許多非均等分佈的數字之一。 – Mankarse

+4

你的老闆在概率論中沒有必要的知識。 –

+0

好吧,所以,對於V&V壺的拍攝,我現在擁有的是足夠隨機的;是嗎? –

回答

5

首先,您需要使用math.random()前一次運行math.randomseed(),而且最好扔掉前幾個隨機數,因爲前幾個不是在一些實現,隨機,看到Lua math.random not working查看詳細。

math.randomseed(os.time()) 
math.random(); math.random(); math.random() 

其次,即使你翻動一千倍完美平衡的硬幣,你通常不會得到頭的正是 500倍和尾部的500倍。這只是獲得頭部的概率大約是500.如果實驗進行了很多次,那麼您會預期頭部的平均值爲500,但是再次,不是每次都是500。

三,是的,math.random()psudo隨機數發生器。實際上,您不能僅使用計算機生成real隨機數字。 Lua math.random()在內部使用C庫函數rand()。事實上,C rand()函數不是一個好的隨機數生成器。如果隨機性很重要,可以使用一些更好的方法來實現,例如C++隨機引擎或Linux上的dev/random等。

+0

我讀到了,我忽略了在我的實驗中丟掉前幾個數字。謝謝你提醒我。早上我不應該在3點和4點。我要睡覺了。 –

+1

'std :: uniform_int_distribution'不是一個隨機數生成器,它只是後處理隨機數以使得生成的分佈符合某些分佈屬性。它不會爲結果添加任何熵(例如,將rand值分配給分佈仍然會產生嚴重的隨機性)。 C++中的實際隨機數生成器被稱爲引擎('std :: random_device'或'std :: mt19937')。注意,通常你需要_both_正確的引擎和正確的分佈來獲得你想要的數字。 – ComicSansMS

+1

@ComicSansMS你說得對,我已經說過了。 –