C++11标准下的随机数生成


基于srand()和rand()的随机数生成
  1. rand()
    rand()的内部实现是用线性同余法做的,它不是真的随机数,因其周期特别长,故在一定的范围里可看成是随机的。
    用户未设定随机数种子的时候系统默认种子是1,rand()产生的是伪随机数,所以每次执行是都是相同的。若要不同就需要使用下面的srand()函数配合使用。
  2. srand()
    srand()用来设置rand()产生随机数时的随机数种子。参数seed必须是个整数,通常可以利用time(0)或time(NULL)的返回值来当做seed。如果每次seed都设相同值,rand()所产生的随机数值每次就会一样。

举例

#include <iostream>  
using namespace std;  
#include   <stdlib.h>      
#include   <time.h>   
#define MIN 0    //随机数产生的范围      
#define MAX 99  
int main()     
{   
    int i;   
    srand((unsigned)time(NULL));  
    cout<<"Ten random numbers from "<<MIN<<  
          " to "<<MAX<<" :/n"<<endl;     
    for(i=0; i<10; i++)          //产生随机数  
    {  
        cout<<MIN + rand() % (MAX + MIN - 1)<<"/t";  //限制在[MIN,MXA]区间
    }  
    cout<<endl;  
    return   0;     
}   

3- 产生特定范围内的随机数通用表达公式
要取得[a,b)的随机整数,使用(rand() % (b-a))+ a (结果值含a不含b)。
要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a (结果值含a和b)。
要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1 (结果值不含a含b)。
(总的来说,通用公式:a + rand() % n ;其中的a是起始值,n是整数的范围)

c++11标准下随机数的生成更加的灵活,功能更加强大。随机数的生成是在random类中实现的,在使用的时候要包含#include<random>的头文件。该类下包含两类函数,随机数生成引擎和随机数分布函数。

最常用的随机数分布函数是uniform_int_engineuniform_double_engine,分别代表整数型离散型均匀分布和浮点型离散型均匀分布。

最常用的随机数生成引擎是default_random_engine预定义的属技术生成器,由编译器定义。

举例

该程序输出15个整型的随机数

#include <random>
#include <iostream>
#include <ctime>
//该函数接受三个参数分别指定随机数范围和种子,返回int
int random_unint(unsigned int min, unsigned int max, unsigned int seed = 0)
{
    static std::default_random_engine e(seed);
    static std::uniform_int_distribution<int> u(min, max);
    return u(e);
}
int main(void)
{
    for (int i = 0; i < 15; ++i) {
        std::cout << random_unint(0, 15, time(NULL)) << " ";
    }
    std::cout << std::endl;
    return 0;
}

注意

1.一个给定的随机数发生器一直会生成相同的随机数序列。一个函数如果定义了局部的随机数发生器,应该将其(包括引擎和分布对象)定义为static的,这样就存储在全局存储区,否则每次调用函数都会生成相同的序列。也就是说定义成static后每次调用还是之前那个发生器,第一次调用产生一批随机数,再次调用将产生接下来的随机数,否则每次调用产生的都是最前面的那些随机数。

2.依然需要使用time来做为种子产生每个不同时刻都不同的随机序列,但由于time默认返回的是以秒计的时间,所以有可能多次使用的都是相同的种子。

更多推荐

C++11标准下的随机数生成