我有一堆关于随机引擎和分布、它们的成本和交互的问题:
std::random_device一个昂贵的(重型可构造的)对象吗?如果可能,我应该只为我的应用程序创建一个吗?RandomNumberDistribution对象昂贵的对象还是主要取决于具体的分布?在我看来,例如uniform_int_distribution应该是包含分布范围的非常轻的对象,[min, max]并且可能是(?)某种内部状态。random_device,random_engine和之间的交互如何distribution在下面的代码中工作:
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> distr(1, 10);
auto random_value = distr(gen);
Run Code Online (Sandbox Code Playgroud)最后一行会发生什么?分布从随机引擎获取下一个值,然后将其带到所需范围[0, 10]?总是很明显一些对象的内部状态应该在调用后修改:绝对random_device,random_engine但uniform_int_distribution也有一些内部状态?
1)通常不是,初始化要么是微不足道的,要么与某些 PRNG 初始化相当,但是调用operator()可能会访问操作系统以获得安全的随机数,并且成本可能很高。
2)主要取决于分布。它们包含分布参数(如果需要,您可以检索)和可选的一些内部状态(IIRC 大多数实现不会打扰它)。所以初始化分布就像初始化小结构。
3) Distribution对象调用generators operator()未指定次数(从 0 到 ? 次)并从generator产生的位序列创建一个随机数。然后它返回生成的 bumber。它潜在地推进生成器状态,并可能将生成器产生的未使用位存储在分布内部状态中。
random_device可能,甚至没有内部状态,如果它实现为系统 RNG 的句柄。否则,它的状态在第二行前进,当您调用它operator()来生成随机数时,您将用作generator 的种子。