【问题标题】:Build a C++ normal distributed random number generator on Xcode 8.3在 Xcode 8.3 上构建 C++ 正态分布随机数生成器
【发布时间】: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


【解决方案1】:

定义为

template< class RealType = double > class normal_distribution

RealType 在哪里只能使用 float、double 或 long double,否则它是未定义的。

代码应该是

std::normal_distribution<double> distribution (0.0, 1.0);

double random_value = distribution(e2);
return fabs(random_value);

【讨论】:

    猜你喜欢
    • 2018-06-22
    • 2011-01-20
    • 1970-01-01
    • 2014-11-06
    • 1970-01-01
    • 2014-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多