【问题标题】:R random number generator faulty?R随机数发生器有故障?
【发布时间】:2026-01-21 17:50:01
【问题描述】:

我正在研究基础 R 的 RNG,并且很好奇 Mersenne-Twister 的 32 位实现在扩展到需要大量随机数时是否会限制它,所以我做了一个简单的测试:

set.seed(8)
length(unique(runif(1e8)))
# [1] 98845641
1e8 - 98845641
# 1154359

所以事实证明,一亿抽奖中确实有很多重复。

当我切换到dqrng包实现的64位版本的MT RNG时,问题没有出现。

问题一:

所引用的64位是指使用的浮点数的类型?

问题2:

我是否可以得出这样的结论,因为可能的数字跨度很大(64 位 FP 与 32 位 FP),使用 64 位 MT 时重复的可能性较小?

【问题讨论】:

  • @Roland,如果是这种情况,在不同的 PRNG 上执行相同的命令应该会产生类似的结果,但事实并非如此。我认为 unique 确实与 identical 非常匹配。试试unique(c(pi, pi + 1e-10))

标签: r random


【解决方案1】:

来自?Random

不要依赖来自 RNG 的低位随机性。大多数提供的统一生成器返回 32 位整数值,这些值转换为双精度值,因此它们最多采用 2^32 个不同的值,长时间运行将返回重复值。

确实,当我们计算expected number of draws that have a duplicate时,我们得到

M <- 2^32
n <- 1e8
(n * (1 - (1 - 1 / M)^(n - 1))) / 2
# [1] 1150705

这与您的结果非常接近。

【讨论】:

  • 最好添加对 R 的 Random 文档的完整参考。因为您仍然可以使用“Wichmann-Hill”算法生成 32 位的唯一数字。 RNGkind(kind = "Wichmann-Hill")1e8 - length(unique(runif(1e8))) = 0