c++ - repetir - randomize en c
Las distribuciones de números aleatorios C++ 11 no son consistentes en todas las plataformas, ¿qué alternativas hay? (1)
Creé mis propias distribuciones de C ++ 11:
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;
};
La distribución uniforme parece ofrecer buenos resultados y la distribución normal ofrece muy buenos resultados:
100000 valores -> 68.159% dentro de 1 sigma; 95.437% dentro de 2 sigma; 99.747% dentro de 3 sigma
La distribución normal usa el método Box-Muller, que según lo que he leído hasta ahora, no es el método más rápido, pero funciona más rápido para mi aplicación.
Tanto la distribución uniforme como la normal deberían funcionar con cualquier motor C ++ 11 (probado con std :: mt19937) y proporciona la misma secuencia en todas las plataformas , que es exactamente lo que yo quería.
Estoy buscando un conjunto de distribuciones portátiles para los motores estándar C ++ 11 como `std :: mt19937 ''(ver http://en.cppreference.com/w/cpp/numeric/random ).
Las implementaciones del motor se desempeñan de manera consistente (es decir, la misma secuencia generada en diferentes plataformas, probadas con Clang y MSVC), pero las distribuciones parecen implementarse de manera diferente en las diferentes plataformas.
Entonces, aunque los motores producen la misma secuencia, parece que una distribución (por ejemplo, std::normal_distribution<double>
) no usa el mismo número de muestras (es decir, produce resultados diferentes) en las diferentes plataformas, lo que no es aceptable en mi caso.
¿Existe tal vez una lib de terceros que pueda usar que siga las plantillas aleatorias de C ++ 11, pero que ofrecerá valores consistentes en las plataformas populares (mirando el soporte en GCC, MSVC y Clang / llvm).
Las opciones que he analizado hasta ahora son:
- Boost.random (un poco pesado, pero vale la pena ya que coincide bastante bien con las contrapartidas de c ++ 11)
- Clonación desde libstd ++ (también vale la pena y probablemente sea portable, pero sacar funciones específicas puede no ser sencillo)
- Creando mis propias distribuciones aleatorias similares a C ++ 11
Necesito uniforme, normal, veneno y Rayleigh.