C ++ 11的随机数分布是跨平台并不一致 - 有什么替代品呢? [英] C++11 random number distributions are not consistent across platforms -- what alternatives are there?

查看:500
本文介绍了C ++ 11的随机数分布是跨平台并不一致 - 有什么替代品呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我找了一套标准的C ++ 11引擎,如`的std :: mt19937便携式分布(见的 HTTP://en.cp$p$pference.com/w/cpp/numeric/random

I'm looking for a set of portable distributions for the standard C++11 engines like `std::mt19937' (see http://en.cppreference.com/w/cpp/numeric/random).

该发动机实现始终如一地执行(即相同的序列在不同平台上产生的 - 与锵和MSVC测试),但发行似乎在不同的平台上的实现方式不同。

The engine implementations perform consistently (i.e. same sequence generated on different platforms – tested with Clang and MSVC), but the distributions seem to be implemented differently on the different platforms.

因此​​,即使发动机产生相同的序列,似乎分配(例如,的std :: normal_distribution<双> )不使用相同数量的样品在不同的平台,这是不能接受的在我的情况下(即产生不同的结果)。

So, even though the engines produce the same sequence, it seems that a distribution (for example, std::normal_distribution<double>) does not use the same number of samples (i.e. produces different results) on the different platforms, which is not acceptable in my case.

有可能是第三方的lib我可以使用下面的C ++ 11的随机模板,但将在流行的平台上提供一致的值(纵观整个海湾合作委员会的支持,MSVC和锵/ LLVM)。

Is there maybe a 3rd party lib I can use that follows the C++11 random templates, but that will deliver consistent values across popular platforms (Looking at support across GCC, MSVC and Clang/llvm).

我看过迄今为止选项包括:

Options I have looked at so far are:


  • Boost.random(有点重,但值得,因为它的C ++相匹配11同行相当不错)

  • 从libstd克隆++(也犯不着和可能会移植,但是拉出具体功能可能不是直接的)

  • 创建我自己的C ++ 11类随机分布

我需要统一的,正常的,毒物和瑞利。

I need uniform, normal, poison and Rayleigh.

推荐答案

我已经创建了自己的C ++ 11的分布:

I have created my own C++11 distributions:

template <typename T>
class UniformRealDistribution
{
 public:
    typedef T result_type;

 public:
    UniformRealDistribution(T _a = 0.0, T _b = 1.0)
        :m_a(_a),
         m_b(_b)
    {}

    void reset() {}

    template <class Generator>
    T operator()(Generator &_g)
    {
        double dScale = (m_b - m_a) / ((T)(_g.max() - _g.min()) + (T)1); 
        return (_g() - _g.min()) * dScale  + m_a;
    }

    T a() const {return m_a;}
    T b() const {return m_b;}

 protected:
    T       m_a;
    T       m_b;
};

template <typename T>
class NormalDistribution
{
 public:
    typedef T result_type;

 public:
    NormalDistribution(T _mean = 0.0, T _stddev = 1.0)
        :m_mean(_mean),
         m_stddev(_stddev)
    {}

    void reset()
    {
        m_distU1.reset();
    }

    template <class Generator>
    T operator()(Generator &_g)
    {
        // Use Box-Muller algorithm
        const double pi = 3.14159265358979323846264338327950288419716939937511;
        double u1 = m_distU1(_g);
        double u2 = m_distU1(_g);
        double r = sqrt(-2.0 * log(u1));
        return m_mean + m_stddev * r * sin(2.0 * pi * u2);
    }

    T mean() const {return m_mean;}
    T stddev() const {return m_stddev;}

protected:
    T                           m_mean;
    T                           m_stddev;
    UniformRealDistribution<T>  m_distU1;
};

均匀分布,似乎提供了良好的效果和正常分布提供了很好的效果:

The uniform distribution seems to deliver good results and the normal distribution delivers very good results:

100000价值观 - > 68.159%,1西格玛之内; 2西格玛内的95.437%; 3西格玛内99.747%

100000 values -> 68.159% within 1 sigma; 95.437% within 2 sigma; 99.747% within 3 sigma

正态分布采用箱穆勒的方法,它根据什么我迄今阅读,不是最快的方法,但它运行更多的速度不够快,我的应用程序。

The normal distribution uses the Box-Muller method, which according to what I have read so far, is not the fastest method, but it runs more that fast enough for my application.

无论是均匀和正态分布应该与任何C ++ 11的发动机(带的std :: mt19937测试)和工作的所有平台上提供相同的序列,这正是我想要的。

Both the uniform and normal distributions should work with any C++11 engine (tested with std::mt19937) and provides the same sequence on all platforms, which is exactly what I wanted.

这篇关于C ++ 11的随机数分布是跨平台并不一致 - 有什么替代品呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆