最大化范围内唯一随机数的数量

时间:2018-01-16 23:29:23

标签: c++11

我正在尝试使用mt19937引擎和std :: random_device作为种子源生成均匀分布的随机数。如果我幸运的话,我会从40亿个可能值中获得数十万个唯一数字。我想知道它是否能比这更好。

我尝试使用高分辨率计时器增加熵,使用seed_seq(https://stackoverflow.com/a/34493057/5852409)的随机设备也尝试初始化mt19937(https://codereview.stackexchange.com/a/109266)的所有624个状态。但是,没有看到任何改进。

#include <random>
#include <iostream>
#include <set>

void main()
{
    std::random_device rd;
    std::mt19937 engn(rd());
    std::uniform_int_distribution<unsigned int> unidist(0, 0xFFFFFFFF - 1);

    std::set<unsigned int> s;
    auto itr = s.insert(unidist(engn));
    int k = 0;
    while (itr.second)
    {
        itr = s.insert(unidist(engn));
        k++;
    }
    std::cout << k << '\n';
}

1 个答案:

答案 0 :(得分:2)

首先,请确保您了解birthday paradox。即事实上你在十几万个数字后得到一个副本表示mt19937中存在统计缺陷。

作为由于这个悖论的粗略估计,即使对于完美随机生成器,在可能值的平方根之后也可能出现重复,在这种情况下,在大约2 ^ 16 = 65536个值之后。 / p>

其次,请注意,熵并不意味着输出的唯一性。想象一下,扔掉一个完美公平的100面模具100次。至少一个值出现两次的可能性实际上远大于每个值恰好一次看到的可能性。熵是衡量系统中状态数的指标。您案例中的熵与种子质量有关(涵盖PRNG的许多不同初始状态),而不是产出的唯一性。

第三,如果你有一个必须确保唯一性(例如ID或句柄)的用例,但你需要较差的可预测性(即随机性),你基本上有两种选择:

  • 商店&#34;采取&#34;值和&#34;重新滚动&#34;只要有必要。此外还有probabilistic algorithms可以检测重复数据的内存少得多,但代价是误报率很小。
  • 使用更大的 - 超过两倍的位 - 处理空间并希望不会发生碰撞。如果偶尔的碰撞是不受欢迎的,但伤害有限,例如导致理论上不必要的重新计算,这是合适的。