【问题标题】:C++ Boost random numeric generation problemC++ Boost随机数字生成问题
【发布时间】:2011-05-18 18:35:56
【问题描述】:

我必须使用 boost 库生成一个随机数,我使用以下代码:

boost::mt19937 gen;
boost::uniform_int<> dist(kUIMinManPort, kUIMaxManPort);
boost::variate_generator< boost::mt19937&, boost::uniform_int<> >
var(gen, dist);
unsigned int value = (unsigned int)var();
return boost::lexical_cast<std::string>(value);

显然我导入了所有必要的库。好吧,代码可以编译,但问题是我获得了相同的数字....

好的好的...别担心,在谈论休闲(或更好的伪休闲)数字生成时,我并不是一个新手。我知道我们必须提供一个种子,并且根据这个种子,将提供一系列伪随机数。

所以我的代码变成了这样:

boost::mt19937 gen(static_cast<unsigned int>(std::time(0)));
boost::uniform_int<> dist(kUIMinManPort, kUIMaxManPort);
boost::variate_generator< boost::mt19937&, boost::uniform_int<> >
var(gen, dist);
unsigned int value = (unsigned int)var();
return boost::lexical_cast<std::string>(value);

嗯,问题是每次我调用这个函数(在 for 循环中)我们得到的数字几乎相同。 我怀疑提供给boost随机库的生成核心的时间依赖种子在for循环的时间段内没有变化,这就是为什么每次我运行一个循环并获得一个随机数时得到几乎相同的数字......问题是:如何有效地解决这个问题???我想给出了一个最佳实践......好吧,我不是唯一一个遇到这样问题的人:)

谢谢...

【问题讨论】:

  • 经过一些经验,我会说不要使用 boost::random 例如。产生正常的偏差,但我从来没有遇到过他们的 mersenne twister 的任何问题。
  • 啊,使用 time(0) 作为种子意味着您不会在一秒钟内多次运行程序。我通常在 unix 上使用 time(0) + (long long)getpid() &lt;&lt; 32 之类的东西。 Windows 上有一个等价物。
  • boost::random_device(在 C++0x 中又称为 std::random_device)是比 std::time() 更好的种子来源。但仍不应在循环的每次迭代中调用它。

标签: c++ boost random seed


【解决方案1】:
static boost::mt19937 gen(static_cast<unsigned int>(std::time(0)));

static 确保生成器只创建一次。问题是time 的变化不够快。如果您在同一毫秒内调用您的函数,您将获得完全相同的结果。不幸的是,您的代码是如此之快,以至于您在同一毫秒内调用它。

将生成器设为静态(或单例模式,或全局变量...)将解决问题。

【讨论】:

  • 实际上 time(0) 每秒变化一次!
  • “将生成器设为静态(或单例模式,或全局变量...)”是什么意思?
  • 这正是我所说的。最简单的方法就是说“static boost::mt19937 gen(static_cast(std::time(0)));”。在变量声明中添加“静态”。
  • @Dragontamer5788 嗯,是的,你是对的,但这发生在类的方法中,为了维护我的对象,我不应该创建另一个 gen 实例,而是将其作为类成员静态并将其用于功能对吗?或者在实例化中使用静态时,每隔一次调用该函数,变量将不会再次创建???我希望我很清楚......
  • 理想的RNG只初始化一次(不多也不少)。有很多方法可以做到这一点......“单例”模式,方法的静态,类的静态和类的非静态成员(如果外部类本身是单例)。在不了解您的其余代码的情况下,我无法就哪个是最佳选择提出建议。类的静态、方法的静态、全局变量和单例都解决了手头的问题。所以现在您需要做出决定:哪些方法最适合您的项目?您要将生成器绑定到哪个对象?
猜你喜欢
  • 2017-04-10
  • 1970-01-01
  • 2011-01-16
  • 2023-04-02
  • 2013-10-21
  • 1970-01-01
  • 2016-05-26
  • 2013-06-03
  • 1970-01-01
相关资源
最近更新 更多