文章目录

      • 1.rand()
      • 2.srand()
      • 深入理解
    • 3.C++11生成随机数
      • 深入了解

1.rand()

  1. rand()函数会返回一个随机的数,范围在0到RAND_MAX之间,其中RAND_MAX定义在C标准库<stdlib.h>中,一般是32767或2147483647。

  2. C++标准函数库提供一随机数生成器rand,随机数生成器总是以相同的种子开始(默认为1),所以形成的伪随机数列也相同,失去了随机意义。

#include <iostream>
#include <cstdlib>
using namespace std;
int main(){
	for(int i=0;i<10;i++)
		cout<<rand()%100<<" ";//生成10个100以内随机数
	cout<<endl;
	return 0;
}
result:
41 67 34 0 69 24 78 58 62 64

2.srand()

srand()可以设置rand()产生随机数时的随机种子,不同种子才能得到不同的随机数。一般利用系统时钟一个自动变化的数字来生成每个时间都不同的种子,进而产生不同的随机数。

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main(){
	srand((int)time(0));
	for(int i=0;i<10;i++)
		cout<<rand()%100<<" ";
	cout<<endl;
	return 0;
}
result:
90 29 44 38 65 22 78 19 38 13

一般可以将rand函数进行宏定义替换以便更方便使用

#define random(x) rand()%(x)

产生随机数的范围通式

  • 要取得[a,b)的随机整数,使用(rand() % (b-a))+ a;

  • 要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a;

  • 要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1;

    通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。

  • 要取得a到b之间的随机整数,另一种表示:a + (int)b * rand() / (RAND_MAX + 1)。

  • 要取得0~1之间的浮点数,可以使用rand() / double(RAND_MAX)。

    可以用pow()来控制随机数位

    #define random(x) (int)(((double)rand()/RAND_MAX)*pow(10,rand()%x))
    //生成10^x内随机数
    

深入理解

rand()内部实现机理是线性同余法来实现伪随机数

参考链接:

【编程珠玑】【第一章】rand()函数实现原理和习题解答

线性同余发生器与伪随机数

纯线性同余随机数生成器

3.C++11生成随机数

C++11提供了随机数库random来生成随机库,头文件random。

random库的组件主要有随机数引擎和随机数分布引擎。

random库通过随机数引擎类random_number_engines产生随机数序列,随机数分布类(random-number distribution)使用随机数引擎生成服从特定概率分布的随机数。

  • 随机数引擎类是可以独立运行的随机数发生器,它以均匀的概率生成某一类型的随机数,但无法指定随机数的范围、概率等信息。因此,它也被称为“原始随机数发生器”,由于不能指定生成随机数的范围,它通常不会被单独使用。
  • 随机数分布类是一个需要于随机数引擎类的支持才能运行的类,但是它能根据用户的需求利用随机数引擎生成符合条件的随机数,例如某一区间、某一分布概率的随机数。

随机数类一般常用的有:

 default_random_engine:随机非负数(不建议单独使用);
 uniform_int_distribution:指定范围的随机非负数;
 uniform_real_distribution:指定范围的随机实数;  
 bernoulli_distribution:指定概率的随机布尔值。

基本用法

#include <iostream>
#include <random>
using namespace std;
int main(){
	default_random_engine e;
	//创建引擎
	for(int i=0;i<10;i++)
		cout<<e()<<endl;
	//生成10个随机数 
    //生成随机数的范围
	cout<<"最小值:"<<e.min()<<endl;
	cout<<"最大值:"<<e.max()<<endl;
	return 0;
}

default_random_engine 是一个随机数引擎类。它定义的调用运算符返回一个随机的 unsigned 类型的值。

随机数引擎是函数对象,所以需要用e()去生成随机数。程序每次运行都会生成相同的随机数序列,想要生成不同的随机数序列可以设置随机数引擎的种子来改变引擎状态。

#include <iostream>
#include <random>
#include <ctime>
using namespace std;
int main(){
	default_random_engine e;//或者直接改变种子,例如e(2)
	e.seed(time(0));
	//让每次生成的随机数不同,设置种子(定义前后均可设置种子)
	int min=100,max=1000;
	uniform_int_distribution<int> dis(min,max);//创建取值范围
	for(int i=0;i<10;i++)
		cout<<dis(e)<<endl;
    //生成100到1000的int随机数
    cout<<endl;
    return 0;
}

还有一种方法,为了生成不一样的随机数还可以定义引擎和范围时,添加static关键字。

static default_random_engine e;
static uniform_int_distribution<unsigned> u(min,max);
  • uniform_int_distribution是一个随机数分布类,也是个模板类,模板参数为生成随机数的类型(不过只能是 int、unsigned、short、unsigned short、long、unsigned long、long long、unsigned long long 中的一种)。它的构造函数接受两个值,表示随机数的分布范围(闭区间)。
  • uniform_real_distribution 是一个随机数分布类,它也是模板类,参数表示随机数类型(可选类型为 float、double、long double)。构造函数也需要最大值和最小值作为参数。
  • bernoulli_distribution 是一个分布类,但它不是模板类。它的构造函数只有一个参数,表示该类返回 true 的概率,该参数默认为 0.5 ,即返回 true 和 false 的概率相等。

以上是生成平均的随机数,如果想生成非均匀分布的随机数,random库中提供了相应的模板类。

深入了解

http://www.cplusplus/reference/random/

更多推荐

C++的随机数生成