创建具有均值和标准差的高斯随机生成器

时间:2013-11-13 02:29:52

标签: c++ random gaussian normal-distribution

我正在尝试创建一维数组并使用随机数生成器(高斯生成器生成随机数,平均值为70,标准差为10),以在0到100之间填充至少100个数字的数组包容。

我将如何在 C ++ 中执行此操作?

4 个答案:

答案 0 :(得分:26)

C ++ 11 中,使用random headerstd::normal_distribution live example )相对简单:

#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <random>

int main()
{
    std::random_device rd;

    std::mt19937 e2(rd());

    std::normal_distribution<> dist(70, 10);

    std::map<int, int> hist;
    for (int n = 0; n < 100000; ++n) {
        ++hist[std::round(dist(e2))];
    }

    for (auto p : hist) {
        std::cout << std::fixed << std::setprecision(1) << std::setw(2)
                  << p.first << ' ' << std::string(p.second/200, '*') << '\n';
    }
}

如果 C ++ 11 不是一个选项,那么 boost 也提供了一个库( live example ):

#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <random>
#include <boost/random.hpp>
#include <boost/random/normal_distribution.hpp>

int main()
{

  boost::mt19937 *rng = new boost::mt19937();
  rng->seed(time(NULL));

  boost::normal_distribution<> distribution(70, 10);
  boost::variate_generator< boost::mt19937, boost::normal_distribution<> > dist(*rng, distribution);

  std::map<int, int> hist;
  for (int n = 0; n < 100000; ++n) {
    ++hist[std::round(dist())];
  }

  for (auto p : hist) {
    std::cout << std::fixed << std::setprecision(1) << std::setw(2)
              << p.first << ' ' << std::string(p.second/200, '*') << '\n';
  }
}

如果出于某种原因,这些选项都不可能,那么您可以自己推出Box-Muller transform,链接中提供的代码看起来很合理。

答案 1 :(得分:8)

使用Box Muller分布(来自here):

double rand_normal(double mean, double stddev)
{//Box muller method
    static double n2 = 0.0;
    static int n2_cached = 0;
    if (!n2_cached)
    {
        double x, y, r;
        do
        {
            x = 2.0*rand()/RAND_MAX - 1;
            y = 2.0*rand()/RAND_MAX - 1;

            r = x*x + y*y;
        }
        while (r == 0.0 || r > 1.0);
        {
            double d = sqrt(-2.0*log(r)/r);
            double n1 = x*d;
            n2 = y*d;
            double result = n1*stddev + mean;
            n2_cached = 1;
            return result;
        }
    }
    else
    {
        n2_cached = 0;
        return n2*stddev + mean;
    }
}

您可以在wolframe math world

了解更多信息

答案 2 :(得分:3)

在C ++ 11中,您将使用<random>标头提供的功能;创建一个随机引擎(例如std::default_random_enginestd::mt19937,必要时使用std::random_device初始化)和使用您的参数初始化的std::normal_distribution对象;那么你可以一起使用它们来生成你的数字。 Here你可以找到一个完整的例子。

在以前的C ++版本中,您所拥有的只是“经典”C LCG(srand / rand),它只生成[0,MAX_RAND]范围内的普通整数分布;使用它,您仍然可以使用Box-Muller transform生成高斯随机数。 (可能有用的是要注意C ++ 11 GNU GCC libstdc ++的std::normal_distribution使用Marsaglia polar method所示的herein。)。

答案 3 :(得分:2)

使用#include <random>

std::default_random_engine de(time(0)); //seed
std::normal_distribution<int> nd(70, 10); //mean followed by stdiv
int rarrary [101]; // [0, 100]
for(int i = 0; i < 101; ++i){
    rarray[i] = nd(de); //Generate numbers;
}