C++11随机数简介

目录

随机数简介

随机数引擎

随机分布

随机数应用


C++11之前随机数都是使用C函数库rand来生成,此函数生成均匀分布的伪随机数(0~32767);C++11中对随机数生成进行增强。

随机数简介

C++11在<random>中定义了一组类用于实现随机数:

  • 随机数引擎类:生成随机数

  • 随机数分布类:生成满足指定分布的随机数

随机数引擎

标准库提供了一个非确定性随机数生成设备random_device,能产生min()~max()间的一个数字(一般只用作种子,调用代价相对较高:因其产生随机数时会依赖于熵池中的噪声资源,必须等待收集到足够多的噪声才能产生新的种子):

  • Linux的实现是读取/dev/urandom设备;

  • Windows的实现是用rand_s,使用操作系统来生成加密安全的伪随机数;

C++11中常用来做伪随机数算法的有以下几种:

  • linear_congruential_engine线性同余法:速度最快、也常用;

  • mersenne_twister_engine梅森旋转法:生成的随机数质量比较高;

  • substract_with_carry_engine滞后Fibonacci法;

此外default_random_engine是一个实例化的类。它的实现是由编译器厂家决定的,可能用linear_congruential_engine也可能用mersenne_twister_engine实现。常用操作方法:

  • seed(s):使用种子s重置引擎;

  • min()/max():引擎生成的最大、最小值;

  • discard(n):将引擎推进n步(即丢弃n个随机数);

  • operator():获取下一个随机数;

random_device rd;
default_random_engine rg{rd()}; // 若不用rd()初始化,则每次生成的随机数都是一样的
for(size_t i=0; i<10; i++)
    cout << rg() << ", ";

随机分布

通过随机分布模板,可以生成满足指定分布特性的随机数。

  • 均匀分布:uniform_int_distribution(整数,返回[low,upper])和uniform_real_distribution(浮点数,返回[low,upper));

  • 伯努利类型分布:bernoulli_distribution(伯努利分布)、binomial_distribution(二项分布)、 geometry_distribution(几何分布)、negative_biomial_distribution(负二项分布);

  • Rate-based分布:poisson_distribution(泊松分布)、exponential_distribution(指数分布)、gamma_distribution(伽马分布)、weibull_distribution(威布尔分布)、extreme_value_distribution(极值分布);

  • 正态分布:normal_distribution(正态分布)、chi_squared_distribution(卡方分布)、cauchy_distribution(柯西分布)、fisher_f_distribution(费歇尔F分布)、student_t_distribution(t分布)

  • 分段分布:discrete_distribution(离散分布)、piecewise_constant_distribution(分段常数分布)、piecewise_linear_distribution(分段线性分布);

通过随机分布与随机引擎组合,即可方便产生符合指定分布的随机数。

随机数应用

编写一个简单随机数生成类,可以生成单个或一组随机数:

class XRand{
protected:
  random_device m_rd;
  default_random_engine m_re{m_rd()};
  // mt19937 m_re{m_rd()}; 

public:
  int operator()(){
    return Next();
  }

  virtual int Next(){
    return m_re();
  }

  vector<int> Next(int nCount){
    vector<int> vec;
    std::generate_n(back_inserter(vec), nCount, [this](){return Next();});
    return vec;
  }
}

生成满足均匀分布的随机数:

class XUniformRand:public XRand{
  uniform_int_distribution<> m_uni;

public:
  explicit XUniformRand(int nMax, int nMin=0)
    : m_uni{nMin, nMax} {}
  using XRand::Next;

  virtual int Next() override {
    return m_uni(m_re);
  }
}

生成满足正态分布的随机数:

class XNormalRand:public XRand{
  normal_distribution<> m_nor; // 生成的都是浮点数

public:
  explicit XNormalRand(int nMean, int nstddev=1)
    : m_nor{nMean, nstddev} {}
  using XRand::Next;

  virtual int Next() override {
    return (int)m_nor(m_re);
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值