Boost随机库的简单使用:Boost.Random(STL通用)
文章目录
文章内容介绍
Boost.Random是Boost里面的一个随机库,它的第一正式版是在Boost 1.15中提供。它里面提供了大量的随机算法,比如mt19937算法,加权概率,随机密码等。可以很方便的提高编码效率。
本文主要介绍了Boost.Random的一些简单使用本文主要分为四个部分,第一部分为此简单介绍,第二部分为Boost.Random的使用,第四部分为总结。
本文参考的Boost版本为1.74。
Boost随机库的简单使用
生成一个随机的整数
boost::random::mt19937 gen(time((time_t *)NULL));
std::cout << gen() << std::endl;
首先构造一个随机数生成器,这里我们使用mt19937算法的随机数生成器。然后直接将随机数生成器作为一个函数对象使用,便可以得到一个区间为\([0, 2^{32}-1]\)的随机数。
如果要生成64位的随机数,可以使用boost::random:mt19937_64
。相应的,它可以产生区间为\([0, 2^{64}] - 1\)的随机数。
除了mt19937算法以外,Boost.Random还提供了非常多种的平均随机数算法,譬如minstd_rand0
、minstd_rand
、rand48
、ecuyer1988
、knuth_b
等。
除了使用算法生成一个伪随机数外,Boost还提供了一个接口random_device
,可以产生真·随机数。它依赖于系统提供的硬件随机,比如在Linux下会使用/dev/urandom
。理论上来说,提供的硬件随机应该是不会产生错误,或者读取到结尾的。如果发生了,便会抛出std::io_base::failure
异常。使用entropy
方法可以获得随机数生成器的熵值。
生成一个区间的平均概率随机数
一般情况下,我们都是需要生成一个区间内的随机数,这才有一定的使用价值。在C语言中,我们通过以下方法获得
rand()%(upper_bound - lower_bound) + lower_bound
而在Boost中,它为我们提供了一个方法,可以通过定义分布的方法,来生成一个区间的随机整数。
boost::random::uniform_int_distribution<> dis(1, 6);
std::cout << dis(gen) << std::endl;
首先我们定义了一个分布,从这个类的名称我们就可以知道,这是一个平均的整数分布。分布和生成器一样,是一个函数对象,通过输入一个随机数生成器,就可以得到随机区域内的整数。生成的范围为\([min, max]\)
生成随机实数也是类似,生成的范围为\([min, max)\)
boost::random::uniform_real_distribution<> fdis(0, 2);
std::cout << fdis(gen) << std::endl;
除了这些比较常用的平均分布外,Boost还提供了两种使用次数比较多的平均分布:
uniform_smallint
,它和uniform_int_distribution
类似,不过这个分布要求生成的范围要远小于随机数生成器的范围;uniform_01
产生\([0, 1)\)之间的随机数。
按概率生成一个区间的随机整数
这种情况如果使用C语言实现,一般会是这样操作。
// 选择的概率,选择的数据为[0,3]
double prob = {0.1, 0.2, 0.3, 0.4};
double choose_prob = (random() % 100000)/100000.0;
choosed_number = 0;
for (choosed_number = 0; choosed_number < 4; ++choosed_number) {
choose_prob -= prob[choosed_number];
if (choose_prob < 0) break;
}
此时,choosed_number为选择的数据。在Boost.Random中,提供了更为优雅的方法,来实现这一操作。
boost::random::discrete_distribution<> prob_dis({0.1, 0.2, 0.3, 0.4});
std::vector<int> count(4, 0);
for (int loop_i = 0; loop_i < 100000; ++loop_i) {
count[prob_dis(gen)]++;
}
for (int loop_i = 0; loop_i < 4; ++loop_i) {
std::cout << count[loop_i] << ",";
}
std::cout << std::endl;
为了更好的表现数据的分布,我使用了一个计数器,来对10万次实验的结果进行统计。得到结果如下:
可以看到结果的分布和我们设置的概率相近。
当然,部分的时候,我们设置的并不是概率(和为一),而是权重(和可能不为一),这个在discrete_distribution
中也是可行的,也就是:
boost::random::discrete_distribution<> prob_dis({1, 2, 3, 4});
是可行的,而且它们的结果是一致的。
除此之外,还可以通过Boost.range
和函数来设置不同的概率。
一些经典的分布
除了自定义分布外,Boost还提供了许多的经典分布,只需要通过简单的参数设置就可以获得一些经典的分布器。
- 伯努利分布
伯努利分布又称为0-1分布,结果只有0或者1。
- 泊松分布
泊松分布适合于描述单位时间内随机事件发生的次数的概率分布。如某一服务设施在一定时间内受到的服务请求的次数,电话交换机接到呼叫的次数、汽车站台的候客人数、机器出现的故障数、自然灾害发生的次数、DNA序列的变异数、放射性原子核的衰变数、激光的光子数分布等等。
- 正态分布
正态分布又名高斯分布,是一个非常常见的连续概率分布。正态分布在统计学上十分重要,经常用在自然和社会科学来代表一个不明的随机变量。
与STL的对比
STL作为C++的标准库,里面也包含有Random库。根据我的查阅的资料,他们之间的借口大部分是相同的,不过也有一小部分的差异。譬如:
- default_random_engine
STL提供了一个default_random_engine
。但是这个随机数生成器并不好用,也需要输入一个种子,而且当种子相近的时候,其值也非常相近。个人认为随机性并不是特别好。
- random_drive
STL和Boost.Random中的硬件随机数生成器描述相近,但是在我个人实际的使用中,Boost.Random给出的熵值为10(部分使用随机?),STL给出的熵值为0(完全使用随机算法)。
Ref
- https://www.boost.org/doc/libs/1_74_0/doc/html/boost_random/tutorial.html
- https://zh.wikipedia.org/wiki/伯努利分布
- https://zh.wikipedia.org/wiki/泊松分佈
- https://zh.wikipedia.org/wiki/正态分布
博客原文地址:https://www.cnblogs.com/ink19/p/Boost_Random.html
Boost随机库的简单使用:Boost.Random(STL通用)的更多相关文章
- boost/lexical_cast.hpp的简单使用方法_行动_新浪博客
boost/lexical_cast.hpp的简单使用方法_行动_新浪博客 boost/lexical_cast.hpp的简单使用方法 (2010-03-19 16:31:13) ...
- (原创)如何使用boost.asio写一个简单的通信程序(二)
先说下上一篇文章中提到的保持io_service::run不退出的简单办法.因为只要异步事件队列中有事件,io_service::run就会一直阻塞不退出,所以只要保证异步事件队列中一直有事件就行了, ...
- boost编译配置及简单使用
boost编译配置及简单使用 1.下载 http://www.boost.org/ 2.编译: A.解压 boost_1_55_0.zip 到boost路径 B.运行 bootstrap.bat. 会 ...
- Boost.Accumulators累加器的简单使用
Boost.Accumulators是一个累加器,实现的功能很简单,就是对一组数据进行操作,然后可以得到一些特征数据. 由于累加器默认不对数据进行储存操作,所以不能把它作为一个简单的容器使用. 简单使 ...
- Boost.Asio 网络编程([译]Boost.Asio基本原理)
转自:https://m.w3cschool.cn/nlzbw/nlzbw-3vs825ya.html Boost.Asio基本原理 这一章涵盖了使用Boost.Asio时必须知道的一些事情.我们也将 ...
- Array的简单使用(Boost和STL通用)
目录 目录 介绍 使用 Boost和STL的区别 介绍 本来这一次是想简单介绍一下Boost里面的协程库的使用的,但是Boost.Coroutine已经被废弃了,而Boost.Coroutine2目前 ...
- (原创)如何使用boost.asio写一个简单的通信程序(一)
boost.asio相信很多人听说过,作为一个跨平台的通信库,它的性能是很出色的,然而它却谈不上好用,里面有很多地方稍不注意就会出错,要正确的用好asio还是需要花一番精力去学习和实践的,本文将通过介 ...
- 【boost】MFC dll中使用boost thread的问题
项目需要,在MFC dll中使用了boost thread(<boost/thread.hpp>),LoadLibraryEx的时候出现断言错误,去掉thread库引用后断言消失. 百度g ...
- boost库使用:vs2013下boost::container::vector编译出错解决
boost版本:boost_1_55_0 bug报告地址 https://svn.boost.org/trac/boost/ticket/9332 出错信息 has_member_function_c ...
随机推荐
- 用GitHub Pages搭建博客(七)
本篇介绍百度统计.百度搜索 一般来讲,部署了一个网站后,我们需要知道网站的浏览量,以便知道网站是否有人访问. 在Jekyll的模板中,由于国外开发者更多,一般的主题默认都开发了谷歌统计(Google ...
- 配置交换机基于接口划分VLAN(接入层设备作为网关)
组网图形 简介 划分VLAN的方式有:基于接口.基于MAC地址.基于IP子网.基于协议.基于策略(MAC地址.IP地址.接口).其中基于接口划分VLAN,是最简单,最常见的划分方式. 基于接口划分VL ...
- python爬虫09selenium
selenium 变成了爬虫利器 我们先来安装一下 pip install selenium 接着我们还要下载浏览器驱动 小帅b用的是 Chrome 浏览器 所以下载的是 Chrome 驱动 当然你用 ...
- kafka消费者offset存储策略
由于 consumer 在消费过程中可能会出现断电宕机等故障,consumer 恢复后,需要从故 障前的位置的继续消费,所以 consumer 需要实时记录自己消费到了哪个 offset,以便故障恢 ...
- wireguard使用
1.编译与安装 sudo apt-get install libmnl-dev libelf-dev linux-headers-$(uname -r) build-essential pkg-con ...
- JS之DOM(一)
一.DOM简介 什么是DOM?简单地说,DOM是是针对HTML和XML文档的一个API,一套对文档的内容进行抽象和概念化的方法. 学习过ORM的同学可能知道ORM是将数据库中的表映射到类,建立一个表和 ...
- simple-rpc
RPC的实现原理 正如上一讲所说,RPC主要是为了解决的两个问题: 解决分布式系统中,服务之间的调用问题. 远程调用时,要能够像本地调用一样方便,让调用者感知不到远程调用的逻辑. 还是以计算器Calc ...
- linux文件cat/tac/more/less/head/tail/find/vimdiff
ls查看目录文件里的文件: [root@localhost test]# ls a aa b c -d选项查看目录文件自身信息: [root@localhost test]# ll -d drw ...
- 11Linux之软件包管理
11Linux之软件包管理 目录 11Linux之软件包管理 11 软件包管理 11.1 软件包介绍 11.1.1 编程语言分类 11.1.2 三种安装包 11.2 rpm包管理 11.2.1 rpm ...
- 查询osd上的pg数
本文中的命令的第一版来源于国外的一个博客,后面的版本为我自己修改的版本 查询的命令如下: ceph pg dump | awk ' /^pg_stat/ { col=1; while($col!=&q ...