使用boost::random跨平台生成一致的随机数
Consistent random number generation accross platforms with boost::random
我们在项目中使用boost::random已经有一段时间了。最近,一个失败的测试单元让我对它的一个特性很感兴趣:根据使用的分布,不同版本的Boost生成的数字序列可能不同。
这种行为似乎并非在所有分布中都是一致的。大多数情况下,使用具有相同种子的RNG的均匀分布产生相同的结果。诸如normal
、lognormal
、binomial
和discrete
的其他分布可能显示出这些差异。
我整理了一个简单的C++程序来显示这个问题:
#include <iostream>
#include <boost/random.hpp>
#include <stdint.h>
void uniform() {
uint32_t seed = 42;
boost::mt19937 rng(seed);
boost::random::uniform_real_distribution<double> distro(0., 1.);
std::cout << "uniform" << std::endl;
for (int i=0; i<10; ++i) {
std::cout << distro(rng) << std::endl;
}
}
void normal() {
uint32_t seed = 42;
boost::mt19937 rng(seed);
boost::random::normal_distribution<double> distro(0., 1.);
std::cout << "normal" << std::endl;
for (int i=0; i<10; ++i) {
std::cout << distro(rng) << std::endl;
}
}
void discrete() {
uint32_t seed = 42;
boost::mt19937 rng(seed);
std::vector<double> P;
P.push_back(0.3);
P.push_back(0.4);
P.push_back(0.3);
boost::random::discrete_distribution<uint64_t> distro(P.begin(), P.end());
std::cout << "discrete" << std::endl;
for (int i=0; i<10; ++i) {
std::cout << distro(rng) << std::endl;
}
}
int main() {
uniform();
normal();
discrete();
}
这个简单的程序将显示Boost 1.56(在OSX上运行)的不同数字序列:
uniform
0.37454
0.796543
0.950714
0.183435
0.731994
0.779691
0.598658
0.59685
0.156019
0.445833
normal
-0.638714
-0.836808
-0.400566
-0.869232
-0.972045
-0.758932
-1.30435
1.22996
0.249399
0.286848
discrete
1
2
2
1
0
0
0
2
1
2
或者使用Boost 1.50(在Ubuntu 12.10上运行):
uniform
0.37454
0.796543
0.950714
0.183435
0.731994
0.779691
0.598658
0.59685
0.156019
0.445833
normal
-1.25821
1.2655
0.606347
-0.19401
-0.196366
-1.72826
-1.09713
-0.783069
0.604964
0.90255
discrete
2
1
2
1
1
0
1
1
0
1
请注意,均匀分布按预期工作:即,同一种子在两个版本上生成一致的数字序列。正态分布和离散分布的表现并不相同。
有办法"解决"这个问题吗?也就是说,不同的平台是否独立于增强版本生成完全相同的序列?
看起来boost::random并不能保证你用不同版本的boost为某些种子获得相同的数字序列。
例如,在1.56版本中,他们将生成正态分布随机数的算法从Box-Muller方法更改为Ziggurat方法:
https://github.com/boostorg/random/commit/f0ec97ba36c05ef00f2d29dcf66094e3f4abdcde
这种方法速度更快,但也会产生不同的数字序列。
其他发行版可能也进行了类似的更改。均匀分布仍然产生与基本rng的输出相同的结果,基本rng默认为1993年7月的梅森龙卷风。
相关文章:
- 理解boost::asio-async_read在无需读取内容时的行为
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- boost::进程间消息队列引发错误
- 整数不会重复超过随机数
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- 如何通过Boost获得0.5增量的随机数
- 使用Boost分隔接口和随机数生成器类的实现
- 有关使用 boost 生成正常随机数的问题
- 使用boost::random跨平台生成一致的随机数
- 将boost用于长二重的(伪)随机数生成器
- 使用boost生成介于1和9999之间的随机数
- Boost库-不生成不同的随机数
- boost c++正在使用Mersenne Twister算法生成0到1之间的相同随机数
- 可以在运行时选择不同的Boost伪随机数生成器
- 二维数组和boost随机数生成器
- 为什么 boost 的随机数生成(在正态分布上)总是给出相同的值?
- c++ -11中使用boost封装的随机数生成器
- C++-Boost:获取相同的随机数.播种似乎不起作用
- 如何让Boost::random和Matlab产生相同的随机数
- 如何使用boost多精度生成正常的随机数