Max*_*ver 2 c++ random normal-distribution gaussian
我在堆栈溢出中搜索了该函数的一些描述、解释和片段std::normal_distribution<> variable(mean, stddev),并发现了一个特别的实例(如下所列),它对我的目的非常有效,即能够创建和容纳一个随机数根据给定均值和标准差的正态分布。
#include <random>
...
std::mt19937 generator;
double mean = 100.0, stddev = 15.0, example;
std::normal_distribution<double> normal(mean, stddev);
example = normal(generator);
cout << "Normal: " << example << endl;
Run Code Online (Sandbox Code Playgroud)
信用 - /sf/answers/838458561/。
然而,我遇到的一个问题是,随着时间的推移,这段代码的结果变得相当重复和可预测。例如,我反复使用平均值 100 和标准差 15,当运行超过 1000 时,几乎可以肯定的是,至少在我的系统上,一致地生成大约 52.246 和 156.86 的一个实例。
有没有办法操纵这个代码片段,或者如果我理解正确的话,种子,以便它产生每次都足够不同的各种结果,同时仍然遵守正态分布?
由于我对这个函数还是新手,我尝试用std::default_random_engine generator;代替std::mt19937 generator,虽然它产生了不同的结果,但随着时间的推移,它也有类似的重复问题。
Ted*_*gmo 10
您默认构建生成器,这意味着每次构建它时都会使用相同的内部状态对其进行初始化。
每次运行该程序时都会打印相同的 10 个数字:
#include <iostream>
#include <random>
int main() {
std::mt19937 generator;
double mean = 100.0, stddev = 15.0, example;
std::normal_distribution<double> normal(mean, stddev);
for(int i = 0; i < 10; ++i) {
example = normal(generator);
std::cout << "Normal: " << example << '\n';
}
}
Run Code Online (Sandbox Code Playgroud)
如果将生成器的实例化放入循环中,它每次都会打印相同的数字。
您需要做的是为生成器提供种子(一次),并且您可以使用 的实例std::random_device来获得良好的种子。它从熵池中选择一个数字(如果存在 - 它通常这样做):
int main() {
std::mt19937 generator(std::random_device{}());
//...
Run Code Online (Sandbox Code Playgroud)
如果您需要从程序中的多个位置访问生成器,您可以将其设为全局或通过引用传递。thread_local如果涉及到线程,如果没有其他方法来分离线程本地数据,就可以做到。