6

我很惊讶地看到这个程序的输出:

#include <iostream>
#include <random>

int main()
{
    std::mt19937 rng1;
    std::mt19937 rng2;
    std::uniform_real_distribution<double> dist;

    double random = dist(rng1);
    rng2.discard(2);

    std::cout << (rng1() - rng2()) << "\n";

    return 0;
}

is 0- 即std::uniform_real_distribution使用两个随机数来产生double范围 [0,1) 内的随机值。我认为它只会生成一个并重新调整它。经过考虑,我猜这是因为std::mt19937产生 32 位整数,而 double 是这个大小的两倍,因此不够“随机”。

问题:我如何一般地找出这个数字,即随机数生成器和浮点类型是否是任意类型?

编辑:我只是注意到我可以std::generate_canonical改用,因为我只对 [0,1) 的随机数感兴趣。不确定这是否有所作为。

4

1 回答 1

2

对于template<class RealType, size_t bits, class URNG> std::generate_canonical标准(第 27.5.7.2 节)明确定义对统一随机数生成器(URNG)的调用次数为

最大值(1,b / log_2 R),

其中 b 是 RealType 尾数中的位数和作为模板参数提供给 generate_canonical 的位数中的最小值。R 是 URNG 可以返回的数字范围(URNG::max()-URNG::min()+1)。但是,在您的示例中,这不会有任何区别,因为您需要 2 次调用 mt19937 来填充双精度尾数的 53 位。

对于其他分布,该标准没有提供一种通用方法来获取有关 URNG 必须生成多少个数字才能获得一个分布的数字的任何信息。

一个原因可能是,对于某些分布,生成单个分布数所需的均匀随机数不是固定的,并且可能因调用而异。一个例子是std::poisson_distribution,它通常被实现为一个循环,它在每次迭代中绘制一个统一的随机数,直到这些数字的乘积达到某个阈值(参见例如GNU C++ 库的实现(第 1523-1528 行)) .

于 2013-07-27T09:06:05.167 回答