前言

一直知道所谓的"随机数"都是伪随机,事实上也是满足某种规则生成的。有些程序测试时通常需要一个随机数源,但在新标准出现之前,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随机数发生器的更多相关文章

  1. C语言基础(11)-随机数发生器

    一. rand() rand是一个C语言库函数,功能是生成一个随机数.rand需要一个不同的种子,才能生成不同的随机数. 二. srand(int seed) rand需要一个不同的种子,才能生成不同 ...

  2. 文献翻译|Design of True Random Number Generator Based on Multi-stage Feedback Ring Oscillator(基于多级反馈环形振荡器的真随机数发生器设计)

    基于多级反馈环形振荡器的真随机数发生器设计 摘要 真随机数生成器(trng)在加密系统中起着重要的作用.本文提出了一种在现场可编程门阵列(FPGA)上生成真随机数的新方法,该方法以 多级反馈环形振荡器 ...

  3. 浅谈C#随机数发生器

    我们在做能自动生成试卷的考试系统时,常常需要随机生成一组不重复的题目,在.net Framework中提供了一个专门用来产生随机数的类System.Random. 对于随机数,大家都知道,计算机不 可 ...

  4. [nRF51822] 16、nRF51822的随机数生成器,及随机数生成器的一些知识(可以帮您补补随机数发生器的知识)

    1.前言 随机数生成器在通信.加密.图像传输等领域应用广泛,且一般起到关键性作用.我在最近设计的一个近场射频通信协议的碰撞避退算法的过程中,便对此有深深体会. 2.伪随机数发生器 随机数发生器一般包括 ...

  5. boost 随机数发生器

    Random     随机数 在很多应用中都需要使用随机数.本库力求提供一个高效的,通用的随机数库.boost库有多种随机数生成方式.先熟悉一下各种随机数生成器的概念. 数字生成器(Number Ge ...

  6. 玩转X-CTR100 l STM32F4 l RNG硬件随机数发生器

    我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] 本文介绍X-CTR100控制器 STM32F4硬件随 ...

  7. QuantLib 金融计算——数学工具之随机数发生器

    目录 QuantLib 金融计算--数学工具之随机数发生器 概述 伪随机数 正态分布(伪)随机数 拟随机数 HaltonRsg SobolRsg 两类随机数的收敛性比较 如果未做特别说明,文中的程序都 ...

  8. CPP-STL:随机数发生器random_shuffle

    //--------------------------------------------------------------------------- #include <string.h& ...

  9. C++11随机数的正确打开方式

    C++11随机数的正确打开方式 在C++11之前,现有的随机数函数都存在一个问题:在利用循环多次获取随机数时,如果程序运行过快或者使用了多线程等方法,srand((unsigned)time(null ...

随机推荐

  1. php断点续传

    http://www.cnblogs.com/xproer/archive/2012/10/26/2741264.html

  2. I.MX6 Android 永不休眠

    /************************************************************************* * I.MX6 Android 永不休眠 * 说明 ...

  3. 【LeetCode】080. Remove Duplicates from Sorted Array II

    题目: Follow up for "Remove Duplicates":What if duplicates are allowed at most twice? For ex ...

  4. 多级联动下拉菜单--cxSelect

    jquery cxSelect插件 github地址:https://github.com/ciaoca/cxSelect demo地址:http://code.ciaoca.com/jquery/c ...

  5. 用Azure CLI批量上传文件

    在Windows环境下,我们可以使用AzCopy批量上传文件.其效率和传输速率都是非常快的. 在Linux或MacOS环境下,可以使用Azure的CLI实现批量文件的上传. 下面的脚本可以实现此功能. ...

  6. JVM插庄之一:JVM字节码增强技术介绍及入门示例

    字节码增强技术:AOP技术其实就是字节码增强技术,JVM提供的动态代理追根究底也是字节码增强技术. 目的:在Java字节码生成之后,对其进行修改,增强其功能,这种方式相当于对应用程序的二进制文件进行修 ...

  7. 查看,检查,修复pg的命令

    标签(空格分隔): ceph,ceph运维,pg 如果集群状态是HEALTH_ERR 并且有pgs inconsistent,需要进行如下操作: 1. 通过下面的命令查看哪些pg状态不一致: # ce ...

  8. JWT(JSON WEB TOKEN) / oauth2 / SSL

    1: JWT: 为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景.JWT的声明一般被 ...

  9. 浏览器默认标签样式总结及css初始化程序

    html中的大部分的标签都有一些糟糕的样式,有的是标签天然自带的,有的是浏览器默认设置的,我们在写网页时,这些默认的样式就会时不时的跳出来捣一下乱,搞得我们很是无奈.所以成手在写css样式时,一般都会 ...

  10. pig 入门教程(1)

    出处:http://www.codelast.com/ 本文可以让刚接触pig的人对一些基础概念有个初步的了解. 本文大概是互联网上第一篇公开发表的且涵盖大量实际例子的Apache Pig中文教程(由 ...