C++关于随机数的笔记


在C++中生成随机数的方法主要包括 std::rand方法以及 random库方法(C++11)。

std::rand 方法

std::rand方法定义在cstdlib(stdlib.h)中,其作用是产生一个0RAND_MAX之间的整数。其中RAND_MAXcstdlib中定义的一个宏,产生的整数是均匀分布的。

在生成随机数之前可以用std::srand来设置随机数种子,如果不设置的话随机数种子会默认设为1,其结果是每次生成的随机数序列都是一样的

程序示例

例如,产生一个范围为1-6均匀分布的随机数可以用1 + std::rand()/((RAND_MAX + 1u)/6),完整代码如下:

#include <cstdlib>
#include <iostream>
#include <ctime>
#include <vector>

int main() 
{
    
    
    std::srand(std::time(nullptr));                 /* 用当前时间产生一个随机数种子 */
    int random_variable = std::rand();
    std::cout << "随机数的范围是 [0, " << RAND_MAX <<"]\n";
    std::vector<unsigned int> vui = {
    
    1,2,3,4,5,6};  /* 存储各数字出现的次数 */
    int x;
    /* 生成20000个数 */
    for (int n=0; n != 20000; ++n) {
    
    
        x = 1 + std::rand()/((RAND_MAX + 1u)/6);    /* 生成1-6的数字 */
        vui[x-1]++;
    }
    for (int i=0; i<vui.size(); i++){
    
    
        std::cout << "数字: " << i+1 << ", 次数 = " << vui[i] << std::endl;
    }
    return 0;
}

random库方法

在C++11中可以通过random库来生成各种分布的随机数。

random库生成指定分布的随机数序列的步骤如下:

1. 选一个随机数种子
2. 选一个随机数生成器
3. 选一种分布
4. 生成随机数

随机数种子

随机数种子可以直接指定,用当前时间生成或者干脆用随机数生成。

随机数生成器

random库里提供了以下几个随机数生成器可供选择:

  • minstd_rand0
  • minstd_rand
  • mt19937
  • mt19937_64
  • ranlux24_base
  • ranlux48_base
  • ranlux24
  • ranlux48
  • knuth_b
  • default_random_engine
    其中mt19937貌似性能比较好。例如,可以用不同的随机数种子来创建不同随机数生成器:
/* 用指定数字创建默认随机数生成器 */

std::default_random_engine e1(250+1);

/* 用当前时间创建mt19937随机数生成器 */
std::mt19937 e2(std::time(nullptr));

/* 用随机数创建knuth_b生成器 */
std::random_device r;
std::knuth_b e3(r());

随机数分布

random库中提供以下五种分布:

  • 均匀分布(Uniform distributions)
  • 伯努利分布(Bernoulli distributions)
  • 泊松分布(Poisson distributions)
  • 正态分布(Normal distributions)
  • 抽样分布(Sampling distributions)

其中每个分布都对应多种类型,例如均匀分布就含有uniform_int_distributionuniform_real_distribution两种情况,分别返回整数和实数,具体内容可以参见这里

可以通过以下代码创建不同随机数分布:

/* 创建1-6范围内的平均分布(整数) */
std::uniform_int_distribution<int> uniform_dist_int(1, 6);

/* 创建2-4范围内的平均分布(实数) */
std::uniform_real_distribution<float> uniform_dist_int(2, 4);

/* 创建均值为5,标准差为3的正态分布 */
std::normal_distribution<> normal_dist(5,3);

生成随机数

通过将随机数生成器传给随机数分布函数来生成随机数:

/* 产生一个均匀分布的整数 */
int rand1 = uniform_dist_int(e1);

/* 产生一个均匀分布的实数 */
float rand2 = uniform_dist_int(e2);

/* 产生一个正态分布的实数 */
float rand3 = normal_dist(e3);

程序示例

以下是用随机数作为种子,采用mt19937生成器生成0-10之间平均分布的实数的示例程序:

#include <iostream>
#include <vector>
#include <random>

int main(){
    
    
    std::vector<int> vec = {
    
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    float number;
    std::random_device r;											/* 1. 采用随机数作为种子 */
    std::mt19937_64 e1(r());										/* 2. 设置mt19937作为随机数生成器 */
    std::uniform_real_distribution<float> uniform_dist_int(0, 10);	/* 3. 选择均匀实数分布 */
    for (int i=0; i<1000; i++){
    
    
        number = uniform_dist_int(e1);								/* 4. 生成随机数 */
        //std::cout << number << " ";
        vec[(int)number]++;
    }
    std::cout << std::endl;
    for (int i=0; i<vec.size(); i++){
    
    
        std::cout << i << "-" << i+1 << ": " << vec[i] << std::endl;
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/willian113/article/details/106638361