我正在尝试实现以下类:
typedef std::mt19937 Engine;
class Interval
{
public:
double upperBoundary;
double lowerBoundary;
double generateUniformRandomNumber(Engine& engine);
};
Run Code Online (Sandbox Code Playgroud)
我希望这个类在多线程环境中工作.每个线程都有自己的Engine
对象实例,它将传递Engine
给具有随机行为的任何类的对象.
为了统一生成C++ 11方式的随机数,the的实现generateUniformRandomNumber
必须是这样的:
uniform_real_distribution<double> distribution_; // private member of Interval
double Interval::generateUniformRandomNumber(Engine& engine)
{
return distribution_(engine);
}
Run Code Online (Sandbox Code Playgroud)
问题是我不理解C++ 11发行版.我知道C++ 11随机数引擎可以是非常大的对象(几千字节),但是分布呢?起初我认为发行版只是简单的仿函数,它operator()
是一个pure const
函数,但似乎它既不是pure
也不是const
.根据该参考,每个分发实例具有reset()
成员函数.这意味着它有一个潜在的大内部状态或缓存.
我的问题是:
分配是否具有内部状态?如果是,为什么?标准是否说明了这个州的规模?
像我一样做一个实现是一个好主意吗?有没有更好的办法?
分布可能很好,通常会有一些状态.该标准在此不作任何限制.我可以想到可以使用状态的几个原因:
随机数分布通常具有一些参数来配置它.例如,正态分布具有均值和方差参数.这些都是其州的一部分,因为它们必须保持在调用之间.
分发是根据其他一些分发实现的.你真的可以把它想象成一个更复杂的参数.例如,我的beta发布实现保留了两个gamma发行版,每个发行版都有自己的配置.
分布可能会随着时间而改变.没有什么可说的,分发的重复调用需要是独立的.这是reset
成员函数的用武之地.大多数发行版都有独立的调用operator()
,因此reset
函数实际上什么都不做(它的定义是空的).但是,如果您的呼叫是相关的,reset
则应将分发恢复到下一个呼叫独立的状态.
你的实现似乎很好.A uniform_real_distribution<double>
不太可能有更多的状态,你构造它的参数.
查看RandomNumberDistribution 模板策略的文档...
reset()
:
重置分发对象的内部状态。调用此函数后,对分布对象的下一次调用operator()将不依赖于先前对operator()的调用。
这意味着对 的调用operator()
可以更改影响后续对 的调用的状态operator()
。这就是reset()
存在和operator()
不存在的原因const
。
uniform_real_distribution
应该是一个小的简单函子,就像你说的那样。它可能只保存Real
构建它所用的 2 ,而没有其他内容。并且reset()
不应该为那个人做任何事情。