随机数被用在很多场合, 比如数值计算, 游戏, 加密, 测试.
根据场合的不同, 需求的随机数发生器也不尽相同. 可以分为一下三种.
non-deterministic random number generator
pseudo-random number generator
quasi-random number generator
[数字发生器{number generator)]
一个数字发生器是一个函数对象, 对他直接调用operator()就可以.
[随机数发生器(uniform random number generator)]
基于数字发生器, 但是产生的是随机数. 可以通过has_fixed_range指定随机数
是否该有产生范围, 可以通过min_value和max_value来指定随机数产生的范围界
限.
[非确定性随机数发生器(Non-deterministic Uniform Random Number Generator)]
这是真正的"随机数"发生器. 基本上没有可能在标准C++范围之内完成, 所以使
用的random_device类的构造函数需要传入一个字符串来指明随机数发生设备的
位置. 在很多unix下面,就是/dev/urandom.
[伪随机数发生器(Pseudo-Random Number Generator)]
基于随机数发生器. 通过特定的算法和内部状况, 产生确定性的伪随机数序列. 可以通过seed来设定种子.
[Quasi-Random Number Generators(不知道怎么称呼)]
实际上就是对于已知的随机数种子根据特定算法算出来的确定数组, 这在很多场
合就足够的了.
二. 使用
random的文件组织相对复杂, 一般情况下, 直接包含random.hpp是最简单直接的办法.
要声明一个generator来产生随机数, 比如boost::hellekalek1995 generator(13);
boost::hellekalek1995是一个随机数产生器, 13是个随机数种子.
然后声明一个随机数分布(uniform random number distribution)来产生随机数.
比如
boost::uniform_smallint<boost::hellekalek1995> die_gen(generator,1, 6)
然后就可以不停的读取die_gen, 比如
std::cout << dir_gen() << std::endl;
一个最简单的例子比如:
#include <iostream>
#include <boost/random.hpp>
int main()
{
boost::hellekalek1995 generator(17);
boost::uniform_smallint<boost::hellekalek1995> die_gen(generator, 1, 6);
for( int i = 1; i <= 10; i++ )
{
std::cout << die_gen() << std::endl;
}
return 0;
}
|
|
usidc5 | 2011-07-18 12:16 |
简介 概览 uniform_smallint 类模板 uniform_int 类模板 uniform_01 类模板 uniform_real 类模板 bernoulli_distribution 类模板 geometric_distribution 类模板 triangle_distribution 类模板 exponential_distribution 类模板 normal_distribution 类模板 lognormal_distribution 类模板 uniform_on_sphere 类模板 简介 除了 随机数生成器 之外,本库还提供了把一种分布 (通常是生成器产生的均匀分布) 映射到另一种分布的分布函数。(译注:在本节中,“分布”指统计学意义上的分布,而“分布函数”指的是类模板。内部的随机数生成器有时会更一般地被称为“随机数源”。) 对于某一映射通常会有多种实现方案:有的需要较多的空间和对内部随机数源的调用,而有的需要进行较多的费时的运算 (如三角函数)。以下给出的对接口的描述是与具体实现无关的;然而,如果某一实现不能覆盖特定分布的全部值域,或者不符合该分布的统计学性质,该实现是无效的。 分布 描述 实例 uniform_smallint 在小整数集 (远小于内部生成器的值域) 上的离散均匀分布 罐中取物 uniform_int 在整数集上的离散均匀分布;可能会多次调用内部生成器以获得足够多的“随机性” 罐中取物 uniform_01 区间 [0,1) 上的连续均匀分布;此分布是其它分布的重要基础 - uniform_real 实数区间 [min, max) 上的连续均匀分布 随机投下一木棍,其偏转角的弧度数是 [0, 2pi) 上的这种分布 (假设偏转角的分布是均匀的) bernoulli_distribution 伯努利试验 (Bernoulli experiment):布尔离散分布,概率可配置 投掷硬币 (p=0.5) geometric_distribution 几何分布:重复伯努利试验,直到出现某一结果的试验次数 抛掷骰子,记录“6”首次出现时的试验次数 triangle_distribution ? ? exponential_distribution 指数分布 放射性物质发射 alpha 粒子的间隔时间 normal_distribution 无穷次重复伯努利试验的结果计数 投掷硬币 10000 次,记录正面出现的次数 lognormal_distribution 对数正态分布 (lognormal distribution) (有时用于模拟) 流水线工人的工作完成时间 uniform_on_sphere 任意给定维数空间的单位球面上的均匀分布 在地球 (近似看作是球体) 表面任选一点去旅游 分布函数的模板参数总按照下列顺序排列: 内部随机数源 返回类型,其默认值为一合适的类型 (可能无这一参数) 分布函数不再满足输入迭代器 (input iterator) 的需求 (std:24.1.1 [lib.input.iterators]),因为这对于生成器(Generator)接口来说是多余的,还会对所有用户带来运行时的开销。而且,一个诉诸于随机数生成的生成器接口更为"自然"。如果你需要把生成器包装进一个输入迭代器接口,可以使用 迭代器适配器(iterator adaptor)。 下面描述的所有分布函数都保存对随机数源的一个非 const 引用;因此分布函数不是 Assignable;不过它们是 CopyConstructible。复制分布函数将会复制参数值;副本和原分布函数将会使用同一内部随机数源,因此两者会从同一序列中取得随机数。 对于在 概念文档 中已经给出定义的成员,在下面的描述中不会详细说明。 <boost/random.hpp> 中的分布:概览 namespace boost { template<class IntType = int> class uniform_smallint; template<class IntType = int> class uniform_int; template<class RealType = double> class uniform_01; template<class RealType = double> class uniform_real; // discrete distributions template<class RealType = double> class bernoulli_distribution; template<class IntType = int> class geometric_distribution; // continuous distributions template<class RealType = double> class triangle_distribution; template<class RealType = double> class exponential_distribution; template<class RealType = double> class normal_distribution; template<class RealType = double> class lognormal_distribution; template<class RealType = double, class Cont = std::vector<RealType> > class uniform_on_sphere; } uniform_smallint 类模板 概览 #include <boost/random/uniform_smallint.hpp> template<class IntType = int> class uniform_smallint { public: typedef IntType input_type; typedef IntType result_type; static const bool has_fixed_range = false; uniform_smallint(IntType min, IntType max); result_type min() const; result_type max() const; void reset(); template<class UniformRandomNumberGenerator> result_type operator()(UniformRandomNumberGenerator& urng); }; 描述 分布函数 uniform_smallint 是 随机分布 的模型。每次调用都将返回在整数集 {min, min+1, min+2, ..., max} 上均匀分布的随机整数。它假设目的区间长度 (max-min+1) 比内部随机数源小得多,因此不考虑量子化 (quantization) 问题。 令 rout=(max-min+1) 为目的区间 (或其长度),rbase 为随机数源的区间 (或其长度)。今要求产生一均匀分布,即 rout 中任意数 i 的理论概率为 pout(i) = 1/rout。类似地,内部随机数源产生 rbase 上的均匀分布,故有 pbase(i) = 1/rbase。令概率函数 pout_s(i) 描述 uniform_smallint 实际产生的分布函数。对 rout 中的各 i ,(pout_s(i)/pout(i) -1)2 的和应不大于 rout/rbase2 (rbase mod rout)(rout - rbase mod rout)。 模板参数 IntType 应为一类整数的值类型。 注记:上述和式是要求的分布函数 pout(i) 和实际产生的分布函数 pout_s(i) 中各数概率相对差的平方和。其值可由计算 (base_rng mod rout) 来得到,如下:令 r = rbase mod rout。rbase 上的基础分布被折叠到区间 rout 上。数字 i < r 快已被赋以基础分布的 (rbase div rout)+1 个数字,只剩下 (rbase div rout)。因此,对于 i < r,pout_s(i) = ((rbase div rout)+1) / rbase,而对于其它 i,pout_s(i) = (rbase div rout)/rbase。在以上求和公式中替换这一部分,可得到希望的结果。 注记:(rbase mod rout)(rout - rbase mod rout) 的上限是 rout2/4。对于 rout3/(4*rbase2) 的相对量化误差的平方和的上限, 明智的方法是,要么选择一个满足 rbase > 10*rout2 的 rbase,要么确保 rbase 可被 rout 整除。 成员 uniform_smallint(IntType min, IntType max) 效果:构造一 uniform_smallint 函子。min 和 max 分别为输出值域的上下界。 uniform_int 类模板 概览 #include <boost/random/uniform_int.hpp> template<class IntType = int> class uniform_int { public: typedef IntType input_type; typedef IntType result_type; static const bool has_fixed_range = false; explicit uniform_int(IntType min = 0, IntType max = 9); result_type min() const; result_type max() const; void reset(); template<class UniformRandomNumberGenerator> result_type operator()(UniformRandomNumberGenerator& urng); template<class UniformRandomNumberGenerator> result_type operator()(UniformRandomNumberGenerator& urng, result_type n); }; 描述 分布函数 uniform_int 是 随机分布 的模型。每次调用都将返回在整数集 {min, min+1, min+2, ..., max} 上均匀分布的随机整数。 模板参数 IntType 应为一类整数的值类型。 成员 uniform_int(IntType min = 0, IntType max = 9) 需求: min <= max 效果:构造一 uniform_int 对象。min 和 max 为分布的参数。 result_type min() const 返回:分布的 "min" 参数。 result_type max() const 返回:分布的 "max" 参数。 result_type operator()(UniformRandomNumberGenerator& urng, result_type n) 返回:在值域 0 <= x < n 内均匀分布的随机数 x。[注记:可以将一个带有 uniform_int 分布的 variate_generator 对象用于 std::random_shuffe,请见 [lib.alg.random.shuffle]. ] uniform_01 类模板 概览 #include <boost/random/uniform_01.hpp> template<class UniformRandomNumberGenerator, class RealType = double> class uniform_01 { public: typedef UniformRandomNumberGenerator base_type; typedef RealType result_type; static const bool has_fixed_range = false; explicit uniform_01(base_type rng); result_type operator()(); result_type min() const; result_type max() const; }; 描述 分布函数 uniform_01 是 随机分布 的模型。每次调用都将返回在区间 [0...1) 上均匀分布的随机浮点数。这一数值是用 std::numeric_limits<RealType>::digits 个随机二进制位构造而成的,也即浮点数的尾数全都是随机的二进制位。[注记:是否要使这一行为可配置?] 警告:因为偶然的历史原因,此类的构造函数取一 UniformRandomNumberGenerator,且 传值。通常需要的是引用语义,从而生成器可以被“就地”地修改;如果需要引用语义,用引用类型作为 UniformRandomNumberGenerator 的模板参数。 模板参数 RealType 应为一类浮点的值类型,支持双目运算符 +, - 和 /。rng.max()-rng.min()+1 的值必须在其可表示范围内。 base_type::result_type 必须为一类数字的值类型,必须支持到 RealType 的 static_cast<>和双目运算符 -。 注意:当前的实现是有 bug 的,因为在某些情况下不会把尾数全部填充为随机的二进制位。目前尚不知道如何把 (未实现的) boost::bigfloat 类有效地用随机位填满。可能需要一个 traits 类。 成员 explicit uniform_01(base_type rng) 效果:构造一 uniform_01 函子,使用给定的随机数生成器作为内部随机数源。 uniform_real 类模板 概览 #include <boost/random/uniform_real.hpp> template<class RealType = double> class uniform_real { public: typedef RealType input_type; typedef RealType result_type; static const bool has_fixed_range = false; uniform_real(RealType min = RealType(0), RealType max = RealType(1)); result_type min() const; result_type max() const; void reset(); template<class UniformRandomNumberGenerator> result_type operator()(UniformRandomNumberGenerator& urng); }; 描述 分布函数 uniform_real 是 随机分布 的模型。每次调用都将返回在区间 [min..max) 上均匀分布的随机浮点数。这一数值是用 std::numeric_limits<RealType>::digits 个随机二进制位构造而成的,也即浮点数的尾数全都是随机的二进制位。 注意:当前的实现是有 bug 的,因为在某些情况下不会把尾数全部填充为随机的二进制位。 成员 uniform_real(RealType min = RealType(0), RealType max = RealType(1)) 需求: min <= max 效果:构造一 uniform_real 对象。min 和 max 是分布的参数。 result_type min() const 返回:分布的 "min" 参数。 result_type max() const 返回:分布的 "max" 参数。 bernoulli_distribution 类模板 概览 #include <boost/random/bernoulli_distribution.hpp> template<class RealType = double> class bernoulli_distribution { public: typedef int input_type; typedef bool result_type; explicit bernoulli_distribution(const RealType& p = RealType(0.5)); RealType p() const; void reset(); template<class UniformRandomNumberGenerator> result_type operator()(UniformRandomNumberGenerator& urng); }; 描述 bernoulli_distribution 类模板的实例是 随机分布 的模型。此分布产生 bool 值,概率满足 P(true) = p 且 P(false) = 1-p。p 是分布的参数。 成员 bernoulli_distribution(const RealType& p = RealType(0.5)) 需求: 0 <= p <= 1 效果:构造一 bernoulli_distribution 对象。p 是分布的参数。 RealType p() const 返回:分布的 "p" 参数。 geometric_distribution 类模板 概览 #include <boost/random/geometric_distribution.hpp> template<class UniformRandomNumberGenerator, class IntType = int> class geometric_distribution { public: typedef RealType input_type; typedef IntType result_type; explicit geometric_distribution(const RealType& p = RealType(0.5)); RealType p() const; void reset(); template<class UniformRandomNumberGenerator> result_type operator()(UniformRandomNumberGenerator& urng); }; 描述 geometric_distribution 类模板的实例是 随机分布 的模型。对整数 i >= 1,产生 i 的概率 p(i) = (1-p) * pi-1,其中 p 是分布的参数。对 UniformRandomNumberGenerator 的每次调用应产生在 [0,1) 上均匀分布的浮点数。 成员 geometric_distribution(const RealType& p = RealType(0.5)) 需求: 0 < p < 1 效果:构造一 geometric_distribution 对象。p 是分布的参数。 RealType p() const 返回:分布的 "p" 参数。 triangle_distribution 类模板 概览 #include <boost/random/triangle_distribution.hpp> template<class RealType = double> class triangle_distribution { public: typedef RealType input_type; typedef RealType result_type; triangle_distribution(result_type a, result_type b, result_type c); result_type a() const; result_type b() const; result_type c() const; void reset(); template<class UniformRandomNumberGenerator> result_type operator()(UniformRandomNumberGenerator& urng); }; 描述 triangle_distribution 类模板的实例是 随机分布 的模型。返回的浮点数 x 满足 a <= x <= c; x 服从三角形分布 (triangle distribution),其中 b 为密度最大的点。对 UniformRandomNumberGenerator 的每次调用应产生在 [0,1) 上均匀分布的浮点数。 成员 triangle_distribution(result_type a, result_type b, result_type c) 效果:构造一 triangle_distribution 函子。a, b, c 是分布的参数。 exponential_distribution 类模板 概览 #include <boost/random/exponential_distribution.hpp> template<class RealType = double> class exponential_distribution { public: typedef RealType input_type; typedef RealType result_type; explicit exponential_distribution(const result_type& lambda); RealType lambda() const; void reset(); template<class UniformRandomNumberGenerator> result_type operator()(UniformRandomNumberGenerator& urng); }; 描述 exponential_distribution 类模板的实例是 随机分布 的模型。对实数 x > 0,其密度 p(x) = lambda * exp(-lambda * x),其中 lambda 是分布的参数。对 UniformRandomNumberGenerator 的每次调用应产生在 [0,1) 上均匀分布的浮点数。 成员 exponential_distribution(const result_type& lambda = result_type(1)) 需求: lambda > 0 效果:构造一 exponential_distribution 对象。lambda 是分布的参数。 RealType lambda() const 返回:分布的 "lambda" 参数。 normal_distribution 类模板 概览 #include <boost/random/normal_distribution.hpp> template<class RealType = double> class normal_distribution { public: typedef RealType input_type; typedef RealType result_type; explicit normal_distribution(const result_type& mean = 0, const result_type& sigma = 1); RealType mean() const; RealType sigma() const; void reset(); template<class UniformRandomNumberGenerator> result_type operator()(UniformRandomNumberGenerator& urng); }; 描述 normal_distribution 类模板的实例是 随机分布 的模型。对任意实数 x,其密度 p(x) = 1/sqrt(2*pi*sigma) * exp(- (x-mean)2 / (2*sigma2) ),其中 mean 和 sigma 是分布的参数。对 UniformRandomNumberGenerator 的每次调用应产生在 [0,1) 上均匀分布的浮点数。 成员 explicit normal_distribution(const result_type& mean = 0, const result_type& sigma = 1); 需求: sigma > 0 效果:构造一 normal_distribution。mean 和 sigma 是分布的参数。 RealType mean() const 返回:分布的 "mean" 参数。 RealType sigma() const 返回:分布的 "sigma" 参数。 lognormal_distribution 类模板 概览 #include <boost/random/lognormal_distribution.hpp> template<class RealType = double> class lognormal_distribution { public: typedef typename normal_distribution<RealType>::input_type typedef RealType result_type; explicit lognormal_distribution(const result_type& mean = 1.0, const result_type& sigma = 1.0); RealType& mean() const; RealType& sigma() const; void reset(); template<class UniformRandomNumberGenerator> result_type operator()(UniformRandomNumberGenerator& urng); }; 描述 lognormal_distribution 类模板的实例是 随机分布 的模型。对实数 x > 0,其密度 p(x) = 1/(x * normal_sigma * sqrt(2*pi)) * exp( -(log(x)-normal_mean)2 / (2*normal_sigma2) ),其中 normal_mean = log(mean2/sqrt(sigma2 + mean2)) 且 normal_sigma = sqrt(log(1 + sigma2/mean2))。对 UniformRandomNumberGenerator 的每次调用应产生在 [0,1) 上均匀分布的浮点数。 成员 lognormal_distribution(const result_type& mean, const result_type& sigma) 效果:构造一 lognormal_distribution 函子。mean 和 sigma 是分布的参数。 uniform_on_sphere 类模板 概览 #include <boost/random/uniform_on_sphere.hpp> template<class RealType = double, class Cont = std::vector<RealType> > class uniform_on_sphere { public: typedef RealType input_type; typedef Cont result_type; explicit uniform_on_sphere(int dim = 2); void reset(); template<class UniformRandomNumberGenerator> const result_type & operator()(UniformRandomNumberGenerator& urng); }; 描述 uniform_on_sphere 类模板的实例是 随机分布 的模型。这一分布产生在 dim 维空间的单位球面上均匀分布的随机坐标。模板参数 Cont 应为一类 STL 的容器,其 begin 和 end 返回 Cont::iterator 类型的非 const 前向迭代器 (non-const forward iterator)。对 UniformRandomNumberGenerator 的每次调用应产生在 [0,1) 上均匀分布的浮点数。 成员 explicit uniform_on_sphere(int dim = 2) 效果:构造一 uniform_on_sphere 函子。dim 是空间的维度。 代码实例: #include "boost/scoped_ptr.hpp" #include <boost/foreach.hpp> #include <string> #include <iostream> #include <vector> #include <list> #include <deque> #include <boost/array.hpp> #include <boost/random.hpp> #include "boost/weak_ptr.hpp" uniform_int<> distribution(1, 100) ; mt19937 engine ; int iCount = 0; variate_generator<mt19937, uniform_int<> > myrandom (engine, distribution); for (int i=0; i<100; ++i) { iCount = myrandom() ; TRACE("%d \r\n",iCount); } |