【发布时间】:2018-11-08 01:09:53
【问题描述】:
我注意到 GNU C++ 标准库的一个非常奇怪的行为。
当使用具有正态分布的自定义生成器时,即使对于相同的生成器结果,分布似乎也可能返回不同的值。
示例代码
#include <iostream>
#include <string>
#include <random>
template <int MAX>
class Generator
{
public:
long long operator()() {return (++state) % MAX;}
long long min() {return 0;}
long long max() {return MAX;}
long long state = 0;
};
int main()
{
// 3 identical generators, 2 identical distributions
Generator<5> gen0, gen1, gen2;
std::normal_distribution<float> dist1(10, 1), dist2(10,1);
// Print: iteration, generator output, distributions output
printf("i gen dist1 dist2\n");
for (int i = 0; i < 10; i++) {
printf("%d %lld %10.6f %10.6f\n", i, gen0(), dist1(gen1), dist2(gen2));
dist2.reset();
}
}
这会产生(g++ 6.2.1,在较新的版本上相同):
i gen dist1 dist2
0 1 11.295982 11.295982
1 2 9.325577 10.256990
2 3 10.256990 9.672720
3 4 8.679697 9.300377
4 0 9.672720 8.957100
5 1 9.097454 11.295982
6 2 9.300377 10.256990
7 3 10.582899 9.672720
8 4 8.957100 9.300377
9 0 10.169774 8.957100
查看第 0 行和第 5 行中的 dist1 结果如何不同,即使生成器生成相同的值 1。对于dist2,它们是相同的,我们称之为reset()。
顺便说一句,原因似乎是 GNU C++ 库成对生成值,并在调用之间缓存它们,不一定调用生成器。这也解释了为什么 dist1 第 4 行与 dist2(重置分布)第 2 行相同。
我在文档中进行了搜索,但无法确定此行为是否符合标准。因此,我不知道这是否是标准库错误:)
注意,据我所见,std::normal_distribution 是唯一表现出这种行为的类。
【问题讨论】:
标签: c++ random normal-distribution c++-standard-library