C++11随机数发生器
前言
一直知道所谓的"随机数"都是伪随机,事实上也是满足某种规则生成的。有些程序测试时通常需要一个随机数源,但在新标准出现之前,C++都是依赖简单的C库函数rand来生成随机数的。最近突然看到了C++11中的随机数发生器,简直如获珍宝,下面会谈一谈这两者的区别。
如何产生随机数
利用C库函数
头文件<stdlib.h>,但是注意在linux下stdlib.h包含srandom 和random ,但在VC下stdlib.h包含的是srand和rand
x = rand()%11; /*产生1~10之间的随机整数*/
y = rand()%51 - 25; /*产生-25 ~ 25之间的随机整数*/
z = ((double)rand()/RAND_MAX)*(b-a) + a;/*产生区间[a,b]上的随机数*/
整理一下常见的产生随机数的通用表达公式为:
取得(0,x)的随机整数:rand()%x;
取得(a,b)的随机整数:rand()%(b-a);
取得[a,b)的随机整数:rand()%(b-a)+a;
取得[a,b]的随机整数:rand()%(b-a+1)+a;
取得(a,b]的随机整数:rand()%(b-a)+a+1;
取得0-1之间的浮点数:rand()/double(RAND_MAX)
比如说随便写个函数:
#define random(x) (rand()%x)
int main()
{
	for (int i = 0; i < 10; ++i)
		cout << random(11) << " ";
	cout << endl;
	system("pause");
}
你会发现两次运行这一段程序输出结果是一样的,说明rand这个函数所生成的随机数是一次性的,为了改进这一点,我们可以利用srand()函数,srand()是用来设置rand()产生随机数时的随机数种子。在调用rand()函数产生随机数前,必须先利用srand()设好随机数种子(seed), 如果未设随机数种子, rand()在调用时会自动设随机数种子为1。上面的两个例子就是因为没有设置随机数种子,每次随机数种子都自动设成相同值1 ,进而导致rand()所产生的随机数值都一样。
而我们一般会用时间来做为种子:
#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
#define random(a,b) (((double)rand()/RAND_MAX)*(b-a)+a)
void main() {
	srand((int)time(0));
	for (int i = 0; i < 100; i++) {
		cout << random(0, 10) << " ";
	}
	cout << endl;
	system("pause");
}
C++随机数发生器
随机数发生器=随机数引擎+随机数分布类
由于C库函数生成的为均匀分布的伪随机整数,但是如果我们需要非均匀分布的数的话,就会手工转换rand生成的随机数的范围、类型和分布,这样又引入了非随机性,不妥。所以我们可以用定义在头文件random中的随机数库通过一组写作的类来解决这些问题:随机数引擎和随机数分布类。引擎是用来生成随机unsigned整数序列的,分布是使用引擎返回服从特定概率分布的随机数。
首先利用引擎来产生随机数:
#include<iostream>
#include<random>
#include<ctime>
using namespace std;
void main() {
	default_random_engine e;   //生成随机无符号数
	for (size_t i = 0; i < 10; ++i)
		cout << e() << " ";
	cout << endl;
	cout << "seed Random:" << endl;
	e.seed(int(time(0)));
	for (size_t i = 0; i < 10; ++i)
		cout << e() << " ";
	system("pause");
}
//OUTPUT:
3499211612 581869302 3890346734 3586334585 545404204 4161255391 3922919429 949333985 2715962298 1323567403
seed Random:
1209134335 963543660 450936573 838635935 555864927 2629301182 2752494759 772597830 1658101593 1483430385 
但是一般来说,随机数引擎的输出是不能直接使用的,因为生成的随机数的值范围通常与我们需要的不符,所以还要加上分布类型,我们再给个完整的例子体会一下:
#include<iostream>
#include<random>
#include<string>
using namespace std;
vector<unsigned> randVec()
{
	static default_random_engine e;
	static uniform_int_distribution<unsigned> u(0, 9);
	vector<unsigned> ret;
	for (size_t i = 0; i < 20; ++i)
		ret.push_back(u(e));
	return ret;
}
vector<float> normalVec()
{
	cout << "正态分布:" << endl;
	static default_random_engine e;
	static normal_distribution<float> n(4, 1.5);//均值4,方差1.5
	vector<float> res;
	vector<unsigned> vals(9);
	for (size_t i = 0; i != 20; ++i)
	{
		unsigned tmp = n(e);
		unsigned v = lround(tmp);
		if (v < vals.size())
			++vals[v];
		res.push_back(tmp);
	}
	for (size_t j = 0; j != vals.size(); ++j)
		cout << j << ": " << string(vals[j], '*') << endl;
	return res;
}
template<typename T>
void display(vector<T> a)
{
	for (int i = 0; i < a.size(); ++i)
	{
		cout << a[i] << " ";
	}
	cout << endl;
}
void main() {
	vector<unsigned> res;
	res=randVec();
	cout << "均匀分布:" << endl;
	display(res);
	vector<float> res2;
	res2 = normalVec();
	display(res2);
	system("pause");
}
结果如下:

更多的分布参数设置见下图:


C++11随机数发生器的更多相关文章
- C语言基础(11)-随机数发生器
		一. rand() rand是一个C语言库函数,功能是生成一个随机数.rand需要一个不同的种子,才能生成不同的随机数. 二. srand(int seed) rand需要一个不同的种子,才能生成不同 ... 
- 文献翻译|Design of True Random Number Generator  Based on Multi-stage Feedback Ring Oscillator(基于多级反馈环形振荡器的真随机数发生器设计)
		基于多级反馈环形振荡器的真随机数发生器设计 摘要 真随机数生成器(trng)在加密系统中起着重要的作用.本文提出了一种在现场可编程门阵列(FPGA)上生成真随机数的新方法,该方法以 多级反馈环形振荡器 ... 
- 浅谈C#随机数发生器
		我们在做能自动生成试卷的考试系统时,常常需要随机生成一组不重复的题目,在.net Framework中提供了一个专门用来产生随机数的类System.Random. 对于随机数,大家都知道,计算机不 可 ... 
- [nRF51822] 16、nRF51822的随机数生成器,及随机数生成器的一些知识(可以帮您补补随机数发生器的知识)
		1.前言 随机数生成器在通信.加密.图像传输等领域应用广泛,且一般起到关键性作用.我在最近设计的一个近场射频通信协议的碰撞避退算法的过程中,便对此有深深体会. 2.伪随机数发生器 随机数发生器一般包括 ... 
- boost 随机数发生器
		Random 随机数 在很多应用中都需要使用随机数.本库力求提供一个高效的,通用的随机数库.boost库有多种随机数生成方式.先熟悉一下各种随机数生成器的概念. 数字生成器(Number Ge ... 
- 玩转X-CTR100 l STM32F4 l RNG硬件随机数发生器
		我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] 本文介绍X-CTR100控制器 STM32F4硬件随 ... 
- QuantLib 金融计算——数学工具之随机数发生器
		目录 QuantLib 金融计算--数学工具之随机数发生器 概述 伪随机数 正态分布(伪)随机数 拟随机数 HaltonRsg SobolRsg 两类随机数的收敛性比较 如果未做特别说明,文中的程序都 ... 
- CPP-STL:随机数发生器random_shuffle
		//--------------------------------------------------------------------------- #include <string.h& ... 
- C++11随机数的正确打开方式
		C++11随机数的正确打开方式 在C++11之前,现有的随机数函数都存在一个问题:在利用循环多次获取随机数时,如果程序运行过快或者使用了多线程等方法,srand((unsigned)time(null ... 
随机推荐
- C++ 播放音频流(PCM裸流)
			直接上代码,如果有需要可以直接建一个win32控制台程序然后将代码拷过去改个文件名就可以用了(注意将声道和频率与你自己的文件对应哦).当然我自己也用VS2008(VS2013好用太多,强烈推荐还是用V ... 
- bzoj3573米特运输
			题意: 给定一棵树上的边和点权 改动点权使得每个父节点u容量为子节点容量的d[u](子节点个数)倍 考察点: 1.这是一道语文题 2.点权很大 直接算会爆 有一种优化办法:取log(醉 这是什么优化) ... 
- maven的配置文件取不同版本
			1. 两个地方需要配置首先是要定义配置源,dev/test/prod对应的配置源需要指定:这是灵活的,可变的:其次要定义配置文件,该配置文件里面的内容采用占位符的方式来编制,在编译打包的过程中要动态根 ... 
- Centos6.5上的iptables
			1.Centos6.5默认开启了iptables 当Centos6.5上安装了MySQL后,在远程连接它,如果出现10060的错误,说明iptables在起作用. 关闭iptables即可,sudo ... 
- GSM/GPRS操作示例
			A6(GPRS) 博文转自安信科技: http://wiki.ai-thinker.com/gprs/examples 1.电话接收 相关指令 ATDxxxxx;//xxx为电话号码 示例 打电话 ... 
- Java标签引起的陷阱
			请看下面的代码,请问下面的代码是否能够通过编译: package com.yonyou.test; /** * 测试类 * @author 小浩 * @创建日期 2015-3-2 */ public ... 
- Python-requests取消SSL验证的警告InsecureRequestWarning解决办法
			使用requests模块请求一个证书无效的网站的话会直接报错 可以设置verify参数为False解决这个问题 # -*- coding:utf-8 -*- __author__ = "Mu ... 
- IIS应用池保持激活工具开发
			之前的 开源一个定时任务调度器 webscheduler 中涉及的定时调用应用已经开始在正式环境中启用,发布到IIS下进行测试,发现一旦应用长时间没有访问(大约半个多小时)就会引发 Applicati ... 
- 基于STM32的三轴数字罗盘HMC5883L模块的测试
			最近买了个数字罗盘模块,调通后发现很不错,非常灵敏,测试的时候精度在1°以内.连续测量模式下,最快测量.输出速率可达75hz,模块每次测量完毕并将数据更新至寄存器后,其DRDY引脚便产生一个低电平脉冲 ... 
- windows、Linux  开放端口
			一.Linux开放端口: 1. CentOS7.x/RedHat7.x , 参考 CentOS7使用firewalld打开关闭防火墙与端口 1.firewalld的基本使用 启动: systemct ... 
