R:runif 的問題:在不到 100 000 步後生成的數字重複(比預期的要多)
執行代碼後
RNGkind(kind="Mersenne-Twister") # the default anyway set.seed(123) n = 10^5 x = runif(n) print(x[22662] == x[97974])
TRUE
是輸出!例如,如果我使用
RNGkind(kind="Knuth-TAOCP-2002")
類似的情況:我在x
. 鑑於兩個隨機發生器的周期,結果似乎極不可能。難道我做錯了什麼?我需要生成至少一百萬個隨機數。
我正在使用帶有 R 版本 3.6.2 的 Windows 8.1;平台:x86_64-w64-mingw32/x64(64 位)和 RStudio 1.2.5033。
其他發現:
- 有一個包 $ n $ 不同的球,我們選擇一個球 $ m $ 次並每次都放回去。概率 $ p_{n, m} $ 所有選擇的球都不同等於 $ {n\choose m} / (n^m m!) $ .
- R 文檔指向一個鏈接,其中提供了用於 64 位機器的 Mersenne-Twister 實現:http: //www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt64.html
均勻抽樣 $ [0, 1] $ 間隔是通過首先選擇一個隨機的 64 位整數獲得的,所以我計算了 64 位的上述概率和(當 $ p_{2^{64}, 10^5} $ 結果相當低)32位案例: $$ p_{2^{64}, 10^5}\doteq 0.9999999999972… \qquad p_{2^{32}, 10^5} \doteq 0.3121… $$
然後,我嘗試了 1000 個隨機種子,併計算了所有生成的數字不同時的案例比例:0.303。
所以,目前,我假設由於某種原因,實際使用了 32 位整數。
R關於隨機數生成的文檔在其末尾有幾句話,證實了您對使用 32 位整數的期望,並可能解釋您所觀察到的內容:
不要依賴來自 RNG 的低階位的隨機性。大多數提供的統一生成器返迴轉換為雙精度的 32 位整數值,因此它們最多采用 2^32 個不同的值,長時間運行將返回重複值(Wichmann-Hill 是例外,並且都給出至少 30 個不同的值位。)
因此,R 中的實現似乎與 Mersenne Twister 的作者網站上解釋的不同。可能將其與生日悖論結合起來,您會期望只有 2^16 個數字的重複項的概率為 0.5,並且 10^5 > 2^16。按照文檔中的建議嘗試 Wichmann-Hill 算法:
RNGkind(kind="Wichmann-Hill") set.seed(123) n = 10^8 x = runif(n) length(unique(x)) # 1e8
請注意,原始 Wichmann-Hill 隨機數生成器具有其下一個數字可以由其前一個數字預測的屬性,因此不滿足有效 PRNG 的不可預測性要求。參見Dutang 和 Wuertz 的這份文件,2009 年(第 3 節)