2014-10-22 143 views
3

我们已经在我们的项目中使用了boost :: random。最近,一个失败的测试单元引起了我对其中一个属性的兴趣:根据所使用的分布,在不同版本的Boost上生成的数字序列可能会有所不同。使用boost :: random的平台随机生成一致随机数

此行为在所有发行版中似乎并不一致。大多数情况下,使用具有相同种子的RNG的均匀分布产生相同的结果。其他分布如normal,lognormal,binomialdiscrete可能会显示出这些差异。

我已经把一个简单的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(); 
} 

这个简单的程序会显示不同的数字序列升压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 

请注意,均匀分布分类如预期那样工作:即,相同的种子在两个版本上产生一致的数字序列。正常和离散分布的行为不一样。

有没有办法“解决”这个?即有不同的平台独立于升压版本生成完全相同的序列?

+2

这里明显的谷歌查询是“提升bug正态分布”。田田。 – 2014-10-22 11:46:27

+1

我在Mac OS X Boost 1.55上试过了你的代码,并得到了与你的Ubuntu和Boost 1.50相同的结果。我有点期待与你的其他结果相匹配!但是现在我们可以从@ HansPassant的提示中看到https://svn.boost.org/trac/boost/ticket/9513这是一个存在高达1.55的bug,并在之后修复。 – 2014-10-22 11:46:59

+0

感谢您的意见和链接。请注意,这不是唯一的问题。我已经扩展了这个例子,以便它也显示了离散分布的问题。 – 2014-10-22 12:05:01

回答

1

看起来boost :: random并不能保证你获得不同版本提升的某些种子的相同数字序列。

E.g.在1.56版本他们已经改变的算法,以产生从所述Box-Muller方法正常分布的随机数的方法Ziggurat

https://github.com/boostorg/random/commit/f0ec97ba36c05ef00f2d29dcf66094e3f4abdcde

这种方法速度较快,但也产生不同数量的序列。

其他分布可能也发生了类似的变化。均匀分布依然会产生相同的结果,默认情况下,基本rng是mersenne twister 19937的输出。