<random>在实践中应该实际使用哪个随机数引擎? std::mt19937?
Which of <random>'s random number engines should one actually use in practice? std::mt19937?
假设你想在实际程序中使用C++<random>
工具(对于"实用"的一些定义——这里的约束是这个问题的一部分(。你的代码大致是这样的:
int main(int argc, char **argv) {
int seed = get_user_provided_seed_value(argc, argv);
if (seed == 0) seed = std::random_device()();
ENGINE g(seed); // TODO: proper seeding?
go_on_and_use(g);
}
我的问题是,你应该使用什么类型ENGINE
?
我过去总是说
std::mt19937
因为它打字很快并且具有知名度。但是现在似乎每个人都在说Mersenne Twister非常重量级且缓存不友好,甚至没有通过其他人所做的所有统计测试。我想说
std::default_random_engine
,因为它是明显的"默认"。但我不知道它是否因平台而异,也不知道它在统计上是否有任何好处。既然现在每个人都在 64 位平台上,我们至少应该使用
std::mt19937_64
而不是std::mt19937
?我想说
pcg64
或xoroshiro128
,因为它们看起来很受人尊敬和轻量级,但它们根本不存在于<random>
。我对
minstd_rand
、minstd_rand0
、ranlux24
、knuth_b
等一无所知——它们一定对某事有好处吗?
显然,这里存在一些相互竞争的限制。
发动机的强度。(
<random>
没有加密强的PRNG,但一些标准化的PRNG仍然比其他的"弱",对吧?sizeof
引擎。其
operator()
的速度.易于播种。 众所周知,
mt19937
很难正确播种,因为它有太多的状态要初始化。库供应商之间的可移植性。如果一个供应商的
foo_engine
产生的数字与另一个供应商的foo_engine
不同,这对某些应用程序不利。(希望这排除了除default_random_engine
之外的任何内容。
尽你所能权衡所有这些限制,你认为最终的"最佳实践留在标准库内"的答案是什么?我应该继续使用std::mt19937
,还是什么?
C++ Reference列出了C++当前提供的所有随机引擎。然而,引擎的选择还有很多不足之处(例如,请参阅我的高质量随机生成器列表(。例如:
default_random_engine
是实现定义的,因此不知道引擎是否存在应用程序可能关心的统计缺陷。linear_congruential_engine
实现了线性同余生成器。但是,除非模数是素数且非常大(至少 64 位(,否则它们的质量往往很差。此外,它们不能接受比其模量更多的种子。minstd_rand0
和minstd_rand
只接受大约 2^31 颗种子。knuth_b
包裹了一只minstd_rand0
,并对它进行了贝斯-达勒姆洗牌。mt19937
和mt19937_64
如果更好地初始化(例如,通过初始化具有多个输出的random_device
,而不仅仅是一个输出的std::seed_seq
(,则可以允许更多的种子,但它们使用大约2500字节的状态。ranlux24
和ranlux48
使用大约 577 位的状态,但它们很慢(它们通过保留一些并丢弃其他伪随机输出来工作(。
但是,C++也有两个引擎可以包裹另一个引擎,以潜在地改善其随机性属性:
discard_block_engine
丢弃给定随机引擎的某些输出。shuffle_order_engine
实现了给定随机引擎的Bays-Durham洗牌。
例如,可以,比如说,有一个mt19937
、ranlux24
的海湾-达勒姆洗牌,或者一个带有shuffle_order_engine
的自定义linear_congruential_engine
。也许包裹的发动机比原来的发动机质量更好。但是,如果不对其进行测试,就很难预测新引擎的统计质量。
因此,在等待此类测试之前,mt19937
似乎是目前C++标准中最实用的引擎。但是,我知道至少有一项提议是将另一个随机数引擎添加到C++的未来版本中(请参阅C++论文P2075(。
根据C++参考,default_random_engine
:
库实现选择的生成器是否至少为相对随意、不专业和/或轻量级的使用提供可接受的引擎行为。
因此,对于轻量级使用,您无需担心任何事情,用Epoch Time (time(0))
播种default_random_engine
,这已经足够好了;)
- 当使用带有VS2019或VSCode的虚幻引擎4.24.2时,我如何修复这些错误的Intellisense错误
- Unity在虚幻引擎4中的"Vector3.Slerp"等效C++?
- 如何创建从Maya(或类似程序)到虚幻引擎的自定义数据导出插件
- 使用std::mt19937从字符串中返回一个随机单词
- 在虚幻引擎中删除NXOpen对象时崩溃
- 引擎节点:未定义的符号:_ZTV6Config
- Agora.io 虚幻引擎插件构建错误
- 如何使用要传递给 mt19937 的可选随机种子参数设计函数
- <random>在实践中应该实际使用哪个随机数引擎? std::mt19937?
- 无法在 Arch Linux 中启动虚幻引擎 4
- 在虚幻引擎中触发C++ dll的事件
- 在 C/C++ 中加载 OpenSSL 自定义引擎
- 组件上的虚幻引擎可蓝图UFUNCTION会导致构建错误
- std::mt19937 in Rcpp
- 使用Visual Studio在虚幻引擎中创建一个新的类c ++给了我太多的错误
- 提高基于组件的游戏引擎的效率
- 在C++中嵌入 Mozilla 的 JavaScript 引擎
- 如何在虚幻引擎4中将char*转换为TCHAR?
- 如何将外部代码包含在虚幻引擎4 C++项目中
- 如何使用虚幻引擎"filter"多播?