文章目录


文章内容介绍

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_rand0minstd_randrand48ecuyer1988knuth_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还提供了两种使用次数比较多的平均分布:

  1. uniform_smallint,它和uniform_int_distribution类似,不过这个分布要求生成的范围要远小于随机数生成器的范围;
  2. 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还提供了许多的经典分布,只需要通过简单的参数设置就可以获得一些经典的分布器。

  1. 伯努利分布

伯努利分布又称为0-1分布,结果只有0或者1。

  1. 泊松分布

泊松分布适合于描述单位时间内随机事件发生的次数的概率分布。如某一服务设施在一定时间内受到的服务请求的次数,电话交换机接到呼叫的次数、汽车站台的候客人数、机器出现的故障数、自然灾害发生的次数、DNA序列的变异数、放射性原子核的衰变数、激光的光子数分布等等。

  1. 正态分布

正态分布又名高斯分布,是一个非常常见的连续概率分布。正态分布在统计学上十分重要,经常用在自然和社会科学来代表一个不明的随机变量。

与STL的对比

STL作为C++的标准库,里面也包含有Random库。根据我的查阅的资料,他们之间的借口大部分是相同的,不过也有一小部分的差异。譬如:

  1. default_random_engine

STL提供了一个default_random_engine。但是这个随机数生成器并不好用,也需要输入一个种子,而且当种子相近的时候,其值也非常相近。个人认为随机性并不是特别好。

  1. random_drive

STL和Boost.Random中的硬件随机数生成器描述相近,但是在我个人实际的使用中,Boost.Random给出的熵值为10(部分使用随机?),STL给出的熵值为0(完全使用随机算法)。

Ref

博客原文地址:https://www.cnblogs.com/ink19/p/Boost_Random.html

Boost随机库的简单使用:Boost.Random(STL通用)的更多相关文章

  1. boost/lexical_cast.hpp的简单使用方法_行动_新浪博客

    boost/lexical_cast.hpp的简单使用方法_行动_新浪博客     boost/lexical_cast.hpp的简单使用方法    (2010-03-19 16:31:13)    ...

  2. (原创)如何使用boost.asio写一个简单的通信程序(二)

    先说下上一篇文章中提到的保持io_service::run不退出的简单办法.因为只要异步事件队列中有事件,io_service::run就会一直阻塞不退出,所以只要保证异步事件队列中一直有事件就行了, ...

  3. boost编译配置及简单使用

    boost编译配置及简单使用 1.下载 http://www.boost.org/ 2.编译: A.解压 boost_1_55_0.zip 到boost路径 B.运行 bootstrap.bat. 会 ...

  4. Boost.Accumulators累加器的简单使用

    Boost.Accumulators是一个累加器,实现的功能很简单,就是对一组数据进行操作,然后可以得到一些特征数据. 由于累加器默认不对数据进行储存操作,所以不能把它作为一个简单的容器使用. 简单使 ...

  5. Boost.Asio 网络编程([译]Boost.Asio基本原理)

    转自:https://m.w3cschool.cn/nlzbw/nlzbw-3vs825ya.html Boost.Asio基本原理 这一章涵盖了使用Boost.Asio时必须知道的一些事情.我们也将 ...

  6. Array的简单使用(Boost和STL通用)

    目录 目录 介绍 使用 Boost和STL的区别 介绍 本来这一次是想简单介绍一下Boost里面的协程库的使用的,但是Boost.Coroutine已经被废弃了,而Boost.Coroutine2目前 ...

  7. (原创)如何使用boost.asio写一个简单的通信程序(一)

    boost.asio相信很多人听说过,作为一个跨平台的通信库,它的性能是很出色的,然而它却谈不上好用,里面有很多地方稍不注意就会出错,要正确的用好asio还是需要花一番精力去学习和实践的,本文将通过介 ...

  8. 【boost】MFC dll中使用boost thread的问题

    项目需要,在MFC dll中使用了boost thread(<boost/thread.hpp>),LoadLibraryEx的时候出现断言错误,去掉thread库引用后断言消失. 百度g ...

  9. boost库使用:vs2013下boost::container::vector编译出错解决

    boost版本:boost_1_55_0 bug报告地址 https://svn.boost.org/trac/boost/ticket/9332 出错信息 has_member_function_c ...

随机推荐

  1. 用GitHub Pages搭建博客(七)

    本篇介绍百度统计.百度搜索 一般来讲,部署了一个网站后,我们需要知道网站的浏览量,以便知道网站是否有人访问. 在Jekyll的模板中,由于国外开发者更多,一般的主题默认都开发了谷歌统计(Google ...

  2. 配置交换机基于接口划分VLAN(接入层设备作为网关)

    组网图形 简介 划分VLAN的方式有:基于接口.基于MAC地址.基于IP子网.基于协议.基于策略(MAC地址.IP地址.接口).其中基于接口划分VLAN,是最简单,最常见的划分方式. 基于接口划分VL ...

  3. python爬虫09selenium

    selenium 变成了爬虫利器 我们先来安装一下 pip install selenium 接着我们还要下载浏览器驱动 小帅b用的是 Chrome 浏览器 所以下载的是 Chrome 驱动 当然你用 ...

  4. kafka消费者offset存储策略

    由于 consumer 在消费过程中可能会出现断电宕机等故障,consumer 恢复后,需要从故 障前的位置的继续消费,所以 consumer 需要实时记录自己消费到了哪个 offset,以便故障恢 ...

  5. wireguard使用

    1.编译与安装 sudo apt-get install libmnl-dev libelf-dev linux-headers-$(uname -r) build-essential pkg-con ...

  6. JS之DOM(一)

    一.DOM简介 什么是DOM?简单地说,DOM是是针对HTML和XML文档的一个API,一套对文档的内容进行抽象和概念化的方法. 学习过ORM的同学可能知道ORM是将数据库中的表映射到类,建立一个表和 ...

  7. simple-rpc

    RPC的实现原理 正如上一讲所说,RPC主要是为了解决的两个问题: 解决分布式系统中,服务之间的调用问题. 远程调用时,要能够像本地调用一样方便,让调用者感知不到远程调用的逻辑. 还是以计算器Calc ...

  8. 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 ...

  9. 11Linux之软件包管理

    11Linux之软件包管理 目录 11Linux之软件包管理 11 软件包管理 11.1 软件包介绍 11.1.1 编程语言分类 11.1.2 三种安装包 11.2 rpm包管理 11.2.1 rpm ...

  10. 查询osd上的pg数

    本文中的命令的第一版来源于国外的一个博客,后面的版本为我自己修改的版本 查询的命令如下: ceph pg dump | awk ' /^pg_stat/ { col=1; while($col!=&q ...