9

我正在尝试使用C++ STD TechnicalReport1扩展来生成正态分布的数字,但是这段代码(改编自这篇文章):

mt19937 eng;
eng.seed(SEED);

normal_distribution<double> dist;
// XXX if I use the one below it exits the for loop
// uniform_int<int> dist(1, 52);

for (unsigned int i = 0; i < 1000; ++i) {
  cout << "Generating " << i << "-th value" << endl;
  cout << dist(eng) << endl;
}

仅打印 1 条“正在生成...”日志消息,然后永远不会退出 for 循环!如果我使用我注释掉的发行版,它会终止,所以我想知道我做错了什么。任何的想法?

非常感谢!

4

4 回答 4

7

我对最初发布的代码有同样的问题,并调查了 GNU 的实现

首先是一些观察:使用 g++-4.4 并使用代码挂起,使用 g++-4.5 并使用 -std=c++0x (即不是 TR1,而是真实的东西)上面的代码有效

恕我直言,TR1 和 c++0x 在随机数生成和随机数消耗之间的适配器方面发生了变化——mt19937 产生整数,normal_distribution 消耗双倍

c++0x 自动使用自适应,g++ TR1 代码不使用

为了让您的代码与 g++-4.4 和 TR1 一起使用,请执行以下操作

std::tr1::mt19937 prng(seed);
std::tr1::normal_distribution<double> normal;
std::tr1::variate_generator<std::tr1::mt19937, std::tr1::normal_distribution<double> > randn(prng,normal);
double r = randn();
于 2010-11-24T11:22:47.107 回答
3

这绝对不会挂起程序。但是,不确定它是否真的满足您的需求。

 #include <random>
 #include <iostream>

 using namespace std;

 typedef std::tr1::ranlux64_base_01 Myeng; 

 typedef std::tr1::normal_distribution<double> Mydist; 

 int main() 
 { 
      Myeng eng; 
      eng.seed(1000);
      Mydist dist(1,10); 

      dist.reset(); // discard any cached values 
      for (int i = 0; i < 10; i++)
      {
           std::cout << "a random value == " << (int)dist(eng) << std::endl; 
      }

 return (0); 
 }
于 2009-07-13T10:36:25.507 回答
2

如果你的 TR1 随机数生成实现是错误的,你可以通过编写你自己的正常生成器来避免 TR1,如下所示。

使用您信任的任何随机生成器生成两个均匀 (0, 1) 随机样本 u 和 v。然后让 r = sqrt( -2 log(u) ) 并返回 x = r sin(2 pi v)。(这称为 Box-Mueller 方法。)

如果您需要具有平均 mu 和标准差 sigma 的正常样本样本,请返回 sigma*x + mu 而不仅仅是 x。

于 2009-09-04T01:54:42.833 回答
1

虽然这似乎是一个错误,但快速确认是传递默认的 0.0、1.0 参数。normal_distribution<double>::normal_distribution()应该等于normal_distribution<double>::normal_distribution(0.0, 1.0)

于 2009-07-13T10:17:49.727 回答