【发布时间】:2017-09-01 14:24:12
【问题描述】:
我正在尝试构建一个函数,该函数返回一个取自 N(0,1) 分布的正随机数。
我在互联网上四处寻找,并尝试使用两种不同的方法。
这是第一个,我尝试从系统时钟设置随机种子。我在Cplusplus.com的这个页面上找到了它:std::normal_distribution::(constructor)
unsigned long normal01_rand() {
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator (seed);
std::normal_distribution<unsigned long> distribution (0.0, 1.0);
long random_value = distribution(generator);
if (random_value < 0) {
random_value = random_value * (-1);
}
return random_value;
}
这是第二个。我不太了解它的详细工作原理,但我发现它是对similar question 的回答,我想试一试:
unsigned long normal01_rand() {
std::random_device rd;
std::mt19937 e2(rd());
std::normal_distribution<unsigned long> distribution (0.0, 1.0);
long random_value = distribution(e2);
if (random_value < 0) {
random_value = random_value * (-1);
}
return random_value;
}
不幸的是,它们都不适合我。如果我使用第一个,当我第一次尝试在我的代码中生成一个随机数时,我的代码会陷入无限循环。第二个反而向我抛出了这个异常:EXC_ARITHMETIC (code=EXC_I386_DIV, subcode=0x0)
我不明白发生了什么以及为什么。
希望已经足够清楚,提前谢谢大家。
【问题讨论】:
-
需要minimal reproducible example 才能确定,但看起来最大的问题是每次输入函数时都在重新创建 PRNG。您应该只创建和播种一次生成器,然后在应用程序的整个生命周期中使用同一个生成器。
-
std:normal_distribution 需要 long double、double 或 float 模板参数。否则你会得到未定义的行为。
-
你的函数名是个谎言,你似乎在尝试的是half-normal,而不是正常的。
-
@jackscorrow 好吧,您可以在函数中将其设为静态,以便仅在第一次调用该函数时对其进行初始化。
-
@jackscorrow 将它放在命名空间中不会改变任何东西。你不需要分配
static,但其他两个应该是。
标签: c++ xcode random macos-sierra normal-distribution