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 ...
随机推荐
- 【转】 Pro Android学习笔记(三三):Menu(4):Alternative菜单
目录(?)[-] 什么是Alternative menu替代菜单 小例子说明 Alternative menu代码 关于Category和规范代码写法 关于flags 多个匹配的itemId等参数 什 ...
- web攻击之六:DNS攻击原理与防范
随着网络的逐步普及,网络安全已成为INTERNET路上事实上的焦点,它关系着INTERNET的进一步发展和普及,甚至关系着INTERNET的生存.可喜的是我们那些互联网专家们并没有令广大INTERNE ...
- MongoDB分析工具之一:explain()语句分析工具
explain(),语句分析工具 MongoDB 3.0之后,explain的返回与使用方法与之前版本有了很大的变化,介于3.0之后的优秀特色和我们目前所使用给的是3.0.7版本,本文仅针对Mongo ...
- UDK编辑器 49条小提示
转自:http://www.cnblogs.com/hmxp8/archive/2012/02/09/2343674.html Very Helpful~ 01. First time using t ...
- 在Golang中使用C语言代码实例
转自:http://www.jb51.net/article/56720.htm cgo 使得在 Golang 中可以使用 C 代码. Hello World 为了有一个较为直观的了解,我们来看一个简 ...
- 最近一直是web前段,没什么意思,所以就不发资料了
最近一直是web前段,没什么意思,所以就不发资料了 版权声明:本文为博主原创文章,未经博主允许不得转载.
- CentOS 7 配置 samba服务器
一.在服务器端上安装软件并进行相关配置(以下操作需用用户root进行): 1.安装samba: yum -y install samba samba-client 2.启动服务并设置开机启动: sys ...
- Servlet编程实例 续1
-----------------siwuxie095 在 LoginServlet 中,右键->Open Type Hierar ...
- DOS查看端口占用及杀掉进程命令
转载自:http://www.cnblogs.com/rainman/p/3457227.html 1. 查看端口占用 在windows命令行窗口下执行: netstat -aon|findstr & ...
- LINQ中的陷阱--TakeWhile&SkipWhile
在用TakeWhile,SkipWhile设置陷阱之前,我们先来看一看他们的兄弟Take和Skip: public static IEnumerable<T> Take<T>( ...