这个类基于 intel Math Kernel Library 的随机数生成器,可以生成平均分布的 int/float/double。保持接口与 C++11 一致,即:对于 int,生成范围是 [a, b];对于 float 与 double,生成范围是 [a, b)。
不需要每次去初始化种子。只需要随时调用即可,每次调用都可以得到不同的随机数。
代码如下(编译时需要指定 -std=c++11):

#ifndef RANDOM_NUMBER_CLASS_H
#define RANDOM_NUMBER_CLASS_H

#include <mkl.h>

template<typename Type>
class Random
{
public:
    Random();
    Random(const Random&) = delete;
    Random(Random&&) = delete;
    Random& operator=(const Random&) = delete;
    Random& operator=(Random&&) = delete;
    ~Random();
    Type operator()(Type left, Type right);
private:
    VSLStreamStatePtr stream;
};

// creates and initializes a random stream
// use Mersenne-Twister pseudorandom number generator: VSL_BRNG_MT19937
// use time counter on CPU instruction level (ASM): __rdtsc()
// __rdtsc() returns the CPU time stamp
template<typename Type>
inline Random<Type>::Random()
{
    vslNewStream(&stream, VSL_BRNG_MT19937, __rdtsc());
}

// deletes the random stream
template<typename Type>
inline Random<Type>::~Random()
{
    vslDeleteStream(&stream);
}

// template specialization: int
// randomly return an int in the section [left, right]
template<>
inline int Random<int>::operator()(int left, int right)
{
    int retValue;
    viRngUniform(VSL_RNG_METHOD_UNIFORM_STD, stream, 1, &retValue, left, right + 1);
    return retValue;
}

// template specialization: float
// randomly return a float in the section [left, right)
template<>
inline float Random<float>::operator()(float left, float right)
{
    float retValue;
    vsRngUniform(VSL_RNG_METHOD_UNIFORM_STD, stream, 1, &retValue, left, right);
    return retValue;
}

// template specialization: double
// randomly return a double in the section [left, right)
template<>
inline double Random<double>::operator()(double left, double right)
{
    double retValue;
    vdRngUniform(VSL_RNG_METHOD_UNIFORM_STD, stream, 1, &retValue, left, right);
    return retValue;
}

#endif // !RANDOM_NUMBER_CLASS_H

使用方法非常简单。以随机生成 int 为例:

Random<int> rand;
int ival = rand(0, 9); // 生成一个在区间 [0, 9] 内的随机数,0 和 9 都包括在内

在循环中使用时也无需再考虑初始化种子的问题,直接使用即可。例如:

Random<int> rand;
for(int i = 0; i < 10; ++i)
    std::cout << rand(0, 9) << std::endl; // 每次输出一个 [0, 9] 区间内的随机整数,无需考虑种子问题

同一个对象可以对不同的区间重复使用,直到此对象析构。例如:

Random<int> rand;
int ival1 = rand(0, 9); // 生成一个 [0, 9] 区间内的随机整数
int ival2 = rand(10, 19); // 生成一个 [10, 19] 区间内的随机整数

转载请注明本文地址 http://blog.csdn/luozhen07/article/details/70257856 。

更多推荐

基于 intel MKL 的高性能随机数生成器