一个C++11随机分布是由什么组成的
What is a C++11 random distribution made of?
我正在尝试实现以下类:
typedef std::mt19937 Engine;
class Interval
{
public:
double upperBoundary;
double lowerBoundary;
double generateUniformRandomNumber(Engine& engine);
};
我希望该类在多线程环境中工作。每个线程都有自己的Engine
对象实例,并将Engine
传递给任何具有随机化行为的类的对象。
为了以C++11的方式均匀地生成随机数,generateUniformRandomNumber
的实现必须是这样的:
uniform_real_distribution<double> distribution_; // private member of Interval
double Interval::generateUniformRandomNumber(Engine& engine)
{
return distribution_(engine);
}
问题是我不了解C++11的发行版。我知道C++11随机数引擎可以是非常大的对象(几千字节(,但分布版呢?起初我认为分布只是简单的函子,其中operator()
是pure const
函数,但它似乎既不是pure
也不是const
。根据参考文献,每个分发实例都有一个reset()
成员函数。这意味着它有一个潜在的大的内部状态,或者可能有一个缓存。
我的问题是:
发行版有内部状态吗?如果是,为什么?标准对这个州的规模有什么规定吗?
像我一样进行实现是个好主意吗?有更好的方法吗?
一个分布可能非常好,通常会有一些状态。这里的标准没有任何限制。我能想到几个可能使用该状态的原因:
-
随机数分布通常有一些参数来配置它。例如,正态分布有均值和方差参数。这些是其状态的一部分,因为它们必须在调用之间保留。
-
该分发是根据其他一些分发来实现的。你真的可以把它看作一个更复杂的参数。例如,我的beta分布实现保留了两个gamma分布,每个gamma分布都有自己的配置。
-
分布可能会随着时间的推移而变化。没有什么可以说对分发的重复调用需要是独立的。这就是
reset
成员函数的作用所在。大多数发行版都有对operator()
的独立调用,因此reset
函数实际上什么都不做(其定义为空(。但是,如果您的调用是依赖的,reset
应该会将分发恢复到下一个调用是独立的状态。
您的实现似乎很好。uniform_real_distribution<double>
的状态不太可能比构造它的参数多得多。
查看文档以获取RandomNumberDistribution模板策略。。。
reset()
:
重置分发对象的内部状态。在呼叫后该函数是对分布对象的operator((的下一次调用将不依赖于以前对运算符((的调用。
这意味着对operator()
的调用可以改变状态,从而影响对operator()
的后续调用。这既是reset()
存在的原因,也是operator()
不是const
的原因。
uniform_real_distribution
应该是一个小的简单函子,就像你说的那样。它可能只容纳2个Real
,而没有其他东西。reset()
不应该对此做任何事情。
是的,分布可以有内部状态。它们通常很小,但如果你担心大小,请检查一下。
reset()
的规范规定:
d的后续使用不依赖于任何引擎在调用reset之前生成的值。
这意味着operator()
的正常调用可能取决于先前调用operator()
时使用的引擎产生的值。也就是说,分发可以缓存或以其他方式依赖于以前的引擎结果。
例如,伯努利分布可能只需要一个比特来产生结果,而给定的引擎一次提供32个比特,因此该分布可能缓存32个比特并且在生成32个值之前不再次调用任何引擎。
另一个例子是一个分布(我忘记了是哪个(,其中公共算法一次自然产生两个值,因此该分布可能会为下一次调用保存第二个值。
所以,是的,分布可以有内部状态。该标准没有对该州的规模提出要求。
如果你问在线程之间共享分发是否可以,那么不可以,这不是一个好主意。首先,这样做是一种数据竞赛,会导致未定义的行为,除非您添加同步或使分发常量(即使您可以通过标准库的实现来实现,这也是不可移植的(。其次,该标准只在以特定方式使用分发和引擎时提供保证,而在多个引擎之间共享分发不是一种方式。共享一个分布不太可能真的会产生糟糕的数据,但国际海事组织不这样做仍然是个好主意。相反,您可能会让每个线程都保留自己的引擎和分布。
- "类模板示例<int>;"语句对 C++11 是什么意思?
- 无法访问的代码 在 C++11 中,可能导致这种情况的原因是什么?
- 在 C++11 线程中,std::mutex 对内存可见性有什么保证?
- C++11中的自动类型扣除和类型转换有什么区别
- 明确定义'static const variable in a struct'对C++ 11 及以上有什么影响吗?
- 有什么理由C++ 11+ std::mutex 应该声明为全局变量,而不是作为函数参数传递到 std::thread 中
- C 11- ctor()=默认和空ctor(){}之间有什么区别
- C++11 大括号/聚合初始化.什么时候使用它?
- C 11中的标准方法是什么,可以访问std :: vector中元素n的指针
- 在 C++11 中表示日内时间 HH:MM:SS 的最佳方法是什么?
- C 11中成员函数的值类别属性是什么?
- C++11 中的默认正则表达式引擎是什么?
- 在 C++11 中获取当前时间的最快方法是什么
- -> 在函数签名中的 c++11 中是什么意思?
- 我的 C++11 测试表明 sort(vector<string>) 甚至比 C++03 慢,有什么错误吗?
- C 11-将变量初始化为参考是什么意思
- C++11 这行代码有什么作用
- 在Apple llvm 4.1上使用libc++与libstc++时,c++11支持的确切区别是什么
- C++11允许对非静态和非常量成员进行类内初始化.发生了什么变化
- 在C#WPF应用程序中使用C++11库的选项是什么