Библиотека BOOST C++: генераторы случайных чисел - моделирование распределений

 

Введение

Synopsis

Шаблон класса uniform_smallint

Шаблон класса uniform_int

Шаблон класса uniform_01

Шаблон класса uniform_real

Шаблон класса bernoulli_distribution

Шаблон класса geometric_distribution

Шаблон класса triangle_distribution

Шаблон класса exponential_distribution

Шаблон класса normal_distribution

Шаблон класса lognormal_distribution

Шаблон класса uniform_on_sphere

Введение

В дополнение к генераторам случайных чисел, библиотека Boost.Random содержит реализации функций распределений, которые отображают одно распределение (обычно равномерное, создаваемое каким-либо генератором) на другое.

Обычно, возможны несколько разных реализаций для получения заданного распределения. Зачастую необходимо делать выбор между использованием дополнительной памяти, большего количества вызовов генератора случайных чисел или более сложных вычислений (трансцендентных функций типа тригонометрических). Данное описание интерфейса не выделяет какую либо конкретную реализацию. Однако реализации, которые не могут обеспечить определенные характеристики распределени, не являются приемлемыми.

распределениеобъяснение пример
uniform_smallint дискретное равномерное распределение на небольшом множестве целых чисел  (значительно меньшем чем диапазон используемого генератора) вытягивание из урны
uniform_int дискретное распределение на множестве целых чисел; используемый генератор может быть вызываться по несколько раз, чтобы достичь необходимой степени случайности на выходе вытягивание из урны
uniform_01 непрерывное равномерное распределение в диапазоне [0,1); является основой для других распределений -
uniform_real непрерывное равномерное распределение в заданном диапазоне [min, max) для действительных чисел для диапазона [0, 2pi): случайное бросание палочки и измерение угла в радианах (подразумевается, что значение угла распределено равномерно)
bernoulli_distribution эксперимент Бернулли: дискретное распределение булевских величин с задаваемыми вероятностями. Биноминальный закон дает вероятность того, что в последовательности из m независимых испытаний событие наступает ровно k раз. подбрасывание монеты (p=0.5).
geometric_distribution measures distance between outcomes of repeated Bernoulli experiments подбрасывание игрального кубика несколько раз и подсчет числа попыток до тех пор, пока не выпадет первая цифра "6"
triangle_distribution ? ?
exponential_distribution экспоненциальное распределение measuring the inter-arrival time of alpha particles emitted by radioactive matter
normal_distribution подсчет числа выходов бесконечного числа повторений экспериментов Бернулли подбрасывание монеты 10000 раз и подсчет, сколько раз выпадет одна из сторон
lognormal_distribution Логнормальное распределение (иногда используется в моделировании). "логарифмически-нормальный закон" встречается у случайных чисел, логарифм которых распределен нормально. Это распределение широко используется в теории надежности; с его помощью аппроксимируются распределения полей атмосферных и промышленных помех. измерение времени выполнения задания рабочим на сборочном конвейере
uniform_on_sphere равномерное распределение на единичной сфере в пространстве с произвольной размерностью выбор случайного точки на глобусе, где предполагается провести следующий отпуск

Параметры шаблонов в функциях распределения всегда перечисляются в следующем порядке:

Замечание: Функции распределений более не удовлетворяют требованиям итераторов (std:24.1.1 [lib.input.iterators]), потому что следование этим требованиям для интерфейса заданного генератора влечет слишком значительные расходы для всех пользователей, включая тех, которым этот интерфейс не нужен. Более того, интерфейс генераторов является более естественным для получения случайных чисел. Используйте iterator adaptor, если необходим генератор с интерфейсом итератора.

Все функции распределения, описанные далее, запоминают неконстантную ссылку на генератор случайных чисел. таким образом, функции распределения не следуют концепции 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

Synopsis

#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 моделирует random distribution. При каждом вызове, эта функция возвращает случайную целую величину, распределенную равномерно на множестве целых чисел {min, min+1, min+2, ..., max}. Подразумевается, что требуемый диапазон (max-min+1) достаточно мал в сравнении с диапазоном случайных чисел, возвращаемых используемым генератором, поэтому реализация данного распределения не содержит код для ограничения или компенсации ошибок дискретизации.

Пусть rout=(max-min+1) - требуемый диапазон целых чисел, и let rbase - диапазон чисел, возвращаемых используемым генератором. Тогда для равномерного распредеения теоретическое значение вероятности для любого числа i в диапазоне rout будет равна pout(i) = 1/rout. Аналогичным образом, предполагается равномерное распределение в диапазоне rbase для исходного генератора чисел. то есть pbase(i) = 1/rbase. Пусть pout_s(i) обозначает случайное распределение, генерируемое uniform_smallint. Тогда сумма (pout_s(i)/pout(i) -1)2 по всем i в диапазоне rout  не должна превышать rout/rbase2 (rbase mod rout)(rout - rbase mod rout).

Параметр шаблона IntType должен быть целым (или аналогичным) типом.

Замечание: Верхняя граница (rbase mod rout)(rout - rbase mod rout) есть rout2/4. Так как верхняя граница суммы квадратов относительных ошибок дискретизации есть rout3/(4*rbase2), то следует либо выбирать такое rbase что rbase > 10*rout2 , либо проверять что rbase делится на rout.

Члены класса

uniform_smallint(IntType min, IntType max)

Эффекты: создается функтор uniform_smallint. Методы min и max являются нижней и верхней границами выходного диапазона, соответственно.

Шаблон класса uniform_int

Synopsis

#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)

Возвращает: Равномерно распределенное число x в диапазоне 0 <= x < n. [Замечание: это позволяет использовать объект variate_generator и распределение uniform_int с std::random_shuffe, см. [lib.alg.random.shuffle]. ]

Шаблон класса uniform_01

Synopsis

#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 случайных двоичных разрядов, то есть мантисса числа с плавающей точкой полностью заполняется случайными битами.

Параметр шаблона RealType должен обозначать тип с плавающей точкой, который поддерживает операторы +, -, и /. Он должен быть достаточным чтобы представлять величину rng.max()-rng.min()+1.

Поле типа base_type::result_type должно быть числовым типом, с поддержкой static_cast<> в RealType и двоичным оператором operator -.

Замечание: текущая реализация содержит ошибку, так как возможно, что не все биты мантиссы заполняются случайными битами. Я не уверен как можно заполнять класс boost::bigfloat случайными битами эффективно. Возможно, это подходящий случай для traits.

Члены класса

explicit uniform_01(base_type & rng)

Эффекты: создается функтор uniform_01 с указанным генератором случайных чисел как источником чисел.

Шаблон класса uniform_real

Synopsis

#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 случайных двоичных разрядов, то есть мантисса числа с плавающей точкой полностью заполняется случайными битами.

Замечание: текущая реализация содержит ошибку, так как возможно, что не все биты мантиссы заполняются случайными битами.

Члены класса

    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

Synopsis

#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 моделирует распределение случайных чисел. Такое распределение возвращает значение true с вероятностью P(true) = p и значение false с вероятностью 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

Synopsis

#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 моделируют распределение случайных чисел. Распределение geometric_distribution генерирует целочисленные случайные величины  i >= 1 с вероятностями p(i) = (1-p) * pi-1. p это параметр распределения.

Члены класса

    geometric_distribution(const RealType& p = RealType(0.5))

Возвращает: 0 < p < 1

Эффекты: создается объект класса geometric_distribution; p является параметром распределения.

   RealType p() const

Возвращает: параметр распределения "p".

Шаблон класса triangle_distribution

Synopsis

#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 имеет треугольное распределение, где b является наиболее вероятным значением для x.

Члены класса

triangle_distribution(result_type a, result_type b, result_type c)

Эффекты: конструируется функтор triangle_distribution. Значения a, b, c являются параметрами распределения.

Шаблон класса exponential_distribution

Synopsis

#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 - параметр распределения.

Члены класса

    exponential_distribution(const result_type& lambda = result_type(1))

Требования: lambda > 0

Эффекты: создается объект класса exponential_distribution использующий rng как источник случайных чисел. lambda - параметр распределения.

    RealType lambda() const

Возвращает: параметр распределения "lambda".

Шаблон класса normal_distribution

Synopsis

#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 являются параметрами распределения.

Члены класса

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

Пример

Пример кода, который создает генератор псевдослучайных величин с нормальным распределением:

#include <boost/random/uniform_01.hpp>
#include <boost/random/normal_distribution.hpp>
#include <boost/random/linear_congruential.hpp>

...

static boost::mt19937 b_rnd;
static boost::uniform_01<boost::mt19937> u_rnd(  b_rnd );
static boost::normal_distribution<double> g_rnd( 0, 1 );

Получение нормальных псевдослучайных чисел делается примерно так:

double x = g_rnd(u_rnd);

Для проверки качества генерируемых чисел можно использовать тестовую программу библиотеки LEM.

Шаблон класса lognormal_distribution

Synopsis

#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 моделируют распределение случайных чисел. Такое распределение генерирует случайные числа с плотностью вероятности p(x) = 1/(x * normal_sigma * sqrt(2*pi)) * exp( -(log(x)-normal_mean)2 / (2*normal_sigma2) ) для x > 0, где normal_mean = log(mean2/sqrt(sigma2 + mean2)) и normal_sigma = sqrt(log(1 + sigma2/mean2)). Другими словами, "логарифмически-нормальный закон" встречается у случайных чисел, логарифм которых распределен нормально. Это распределение широко используется в теории надежности; с его помощью аппроксимируются распределения полей атмосферных и промышленных помех.

Члены класса

lognormal_distribution(const result_type& mean, const result_type& sigma)

Эффекты: создается функтор как объект класса lognormal_distribution. mean и sigma являются средним и стандартным отклонением логнормального распределения.

Шаблон класса uniform_on_sphere

Synopsis

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

Члены класса

explicit uniform_on_sphere(int dim = 2)

Эффекты: создается функтор как объект класса uniform_on_sphere. dim это число измерений сферы.

Jens Maurer, 2001-08-31
Последняя правка: 13.05.2005

библиотека BOOST C++ http://www.boost.org
перевод Elijah Koziev www.solarix.ru

  © Mental Computing 2010