升压随机输出的已知差异从 1.58 到 1.67

Known differences in boost random output from 1.58 to 1.67?

本文关键字:随机 输出      更新时间:2023-10-16

我正在使用一些我没有编写的生成随机数据的遗留代码。 从 1.58 更新到 1.67 提升后,输出发生了变化。通常,可重现的输出由固定的种子密钥发生。但是它们现在在新旧版本之间是不同的。

使用的提升随机分布包括uniform_int、uniform_real、exponential_distribution和normal_distribution。有没有人具体知道其中一个或多个现在与我提到的增强版本不同?

我可能必须编写一个简单的测试程序来确定这一点。

至少在 2016 年 7 月更改为使用(改进版本(Ziggurat 方法的正态分布和指数分布,c.f. https://github.com/boostorg/random/commit/c7d1b4f3516098b3e2fc8f8531d716881ab5834e。此特定更改首次出现在版本 1.62(2016 年 10 月发布(中。我没有及时检查。

我发现正态分布肯定与从另一个答案建模的测试程序不同:Boost随机数生成器。看起来在我的实用程序的典型用法中,我认为它只是使用正常,但指数将由不同的选项触发。无论如何,我确认了我第一次提到的两个版本数千次迭代的差异。然后在看到 Ralf Stubner 的答案(谢谢(后,我做了一些更详尽的测试,我看到 1.64 wrt 1.57 的确认差异。之后,输出再次保持一致,至少达到 1.67。我尝试了 1.57 到 1.67。

编译了一个这样的测试程序:g++ -I/opt/boost_1_57_0 random_example.cc -O3 -o random_example调用方式如下:random_example 0 0 9999999>/tmp/random_example_boost_1_57_0_0_0_9999999.txt

# number of differences in ten million lines
root@ubuntu-02:/tmp# baseline=random_example_boost_1_57_0_0_0_9999999.txt
root@ubuntu-02:/tmp# test=random_example_boost_1_64_0_0_0_9999999.txt
root@ubuntu-02:/tmp# diff -U 0 $baseline $test | grep ^@ | wc -l 
5796
# look at first 5 lines of difference
root@ubuntu-02:/tmp# diff $baseline $test | head -5
261,262c261
< -36.8701
< -3.78609
---
> -38.8405
root@ubuntu-02:/tmp# 

示例代码:

random_example.cc: 
#include <iostream>
#include "boost/random.hpp"
#include "boost/generator_iterator.hpp"
using namespace std;
int main(int argc, char **argv) {
    typedef boost::rand48 RNGType;
    int seed = 0;
    int start = 1;
    int stop = 100;
    if (argc>=2) {
        seed = atoi(argv[1]);
    }
    if (argc>=3) {
        start = atoi(argv[2]);
    }
    if (argc>=4) {
        stop = atoi(argv[3]);
    }
    RNGType rng(seed);
    typedef boost::normal_distribution<> dist_t;
    boost::normal_distribution<> distribution_params(0.0, 10.0);
    boost::variate_generator< RNGType, dist_t >
                dice(rng, distribution_params);
    for ( int i = start; i <= stop; i++ ) {
        double n  = dice();
        cout << n << endl;
    }
}