boost高质量随机数库 zhuan

时间:2023-03-08 21:49:43
boost高质量随机数库 zhuan

shared_ptr<int> tmp2(new int(10)) ;
int * test=tmp2.get();
std::cout<<*test<<" "<<*tmp2<<" "<< * ( (int*)( tmp2.get() ) );

10 10 1011

not 10 10 10

why?

一. 概念
随机数被用在很多场合, 比如数值计算, 游戏, 加密, 测试.

根据场合的不同, 需求的随机数发生器也不尽相同. 可以分为一下三种.

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:04
传统随机数生成器的问题
传统随机数生成器具有几个问题。它们无法生成在用户指定范围内均匀分布的随机数,或者符合高斯或二项式分布的随机数。本文仅在可将随机数映射到某个范围内的上下文中讨论随机数。

Boost 随机数生成器位于 boost/random 文件夹中。此外,为方便起见,boost/ 目录中的 random.hpp 头文件包括了 boost/random 文件夹中的所有其他头文件。
Boost 随机接口划分为两个部分:随机数生成器和随机数必须位于其中的分布。本文讨论 uniform_int 和 uniform_real random-number 分布以及 mt19937 随机数生成器。清单 11 使用了 uniform_int 和 uniform_real 分布。

清单 11. 将 variate_generator 与 mt19937 引擎和 uniform_int 分布一起使用
                
#include <iostream>
#include <boost/random.hpp>
using namespace std;
using namespace boost;

int main ( )
  {
  uniform_int<> distribution(1, 100) ;
  mt19937 engine ;
  variate_generator<mt19937, uniform_int<> > myrandom (engine, distribution);

for (int i=0; i<100; ++i)
    cout << myrandom() << endl;

return 0;
  }

此代码生成介于 1 和 100 之间(包括 1 和 100)的随机数;用于实现随机化的基础引擎是 mt19937。variate_generator 为您组合了该引擎和分布。
清单 12 使用了另一个引擎: kreutzer1986.

清单 12:组合 uniform_real 分布和 kreutzer1986 引擎
                
#include <iostream>
#include <boost/random.hpp>
using namespace std;
using namespace boost;

int main ( )
  {
  uniform_real<> distribution(1, 2) ;
  kreutzer1986 engine ;
  variate_generator<kreutzer1986, uniform_real<> > myrandom (engine, distribution);

for (int i=0; i<100; ++i)
    cout << myrandom() << endl;

return 0;
  }

除了 uniform_int 和 uniform_real 分布以外,Boost 还提供了几个其他分布,包括二项式、泊松和正态分布。

usidc5 2011-07-18 12:08
随机单例的头文件如下

#ifndef _RANDOMHELPER_H
#define _RANDOMHELPER_H

#include <boost/random.hpp>
#include <ctime>
#include <boost/pool/detail/singleton.hpp>
using namespace boost;
using boost::details::pool::singleton_default;

template<typename T> class rng_wrapper//模板类型是随机数发生器
{
private:
    T rng;//随机数发生器成员变量
public:
    rng_wrapper():rng((typename T::result_type)time(0))
    {
    }

typename T::result_type operator()(const int &min,const int &max)//重载调用操作符
    {
        uniform_int<> ui(min,max);
        return ui(rng);
    }

T GetEngine()
    {
        return rng;
    }
};
typedef singleton_default< rng_wrapper<mt19937> > rng_t;

class RandomHelper
{
public:
    RandomHelper(){}
    static int Random(const int &min,const int &max)
    {
        rng_t::object_type &rng = rng_t::instance();        
        return rng(min,max);
    }
};

#endif
调用示例如下:

#include <iostream>

#include "RandomHelper.h"
using namespace std;

int main(void)
{    
    for(int i = 0; i < 100 ; i++)
    {        
        cout << RandomHelper::Random(1,100)<< endl;
    }    
    return 0;
}
欢迎大家多提意见,这里只是实现了整数的随机,其他各类的随机数,只需要修改对应的分布器即可。
关于分布器,可以参考:
http://laokaddk.blog.51cto.com/368606/323858

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);
}