Увеличить генератор случайных чисел
У кого-нибудь есть любимый импульсный генератор случайных чисел, и можете ли вы немного объяснить, как внедрить его в код. Я пытаюсь заставить работать твистер Мерсенна, и мне было интересно, есть ли у кого-нибудь предпочтения по отношению к другим.
3 ответа
Этот код адаптирован из руководства по ускорению по адресу http://www.boost.org/doc/libs/1_42_0/libs/random/index.html:
#include <iostream>
#include "boost/random.hpp"
#include "boost/generator_iterator.hpp"
using namespace std;
int main() {
typedef boost::mt19937 RNGType;
RNGType rng;
boost::uniform_int<> one_to_six( 1, 6 );
boost::variate_generator< RNGType, boost::uniform_int<> >
dice(rng, one_to_six);
for ( int i = 0; i < 6; i++ ) {
int n = dice();
cout << n << endl;
}
}
Чтобы объяснить биты:
mt19937
является твистером Мерсенна, который генерирует необработанные случайные числа. Здесь используется typedef, так что вы можете легко изменить тип генератора случайных чисел.rng
это пример твистера генератора.one_to_six
это экземпляр дистрибутива. Здесь указываются числа, которые мы хотим сгенерировать, и распределение, за которым они следуют. Здесь мы хотим от 1 до 6, распределенных равномерно.dice
это то, что берет необработанные числа и распределение, и создает для нас числа, которые мы на самом деле хотим.dice()
это вызовoperator()
дляdice
объект, который получает следующее случайное число после распределения, имитируя случайный шестисторонний бросок костей.
В нынешнем виде этот код производит одинаковую последовательность бросков кубиков каждый раз. Вы можете рандомизировать генератор в его конструкторе:
RNGType rng( time(0) );
или используя его член seed().
Я нашел эту ссылку, которая дает хороший обзор свойств различных генераторов случайных чисел. Для удобства я скопировал приведенную выше ссылку на таблицу:
+ ----------------------- + ------------------- + ----- ------------------------ + ------------------------ + | генератор | длина цикла | ок. требования к памяти | ок. относительная скорость | +-----------------------+-------------------+-----------------------------+------------------------+ | minstd_rand | 2^31-2 | sizeof(int32_t) | 40 | | rand48 | 2^48-1 | sizeof(uint64_t) | 80 | | lrand48 (библиотека C) | 2^48-1 | - | 20 | | ecuyer1988 | ок. 2^61 | 2*sizeof(int32_t) | 20 | | kreutzer1986 |? | 1368*sizeof(uint32_t) | 60 | | hellekalek1995 | 2^31-1 | sizeof(int32_t) | 3 | | mt11213b | 2^11213-1 | 352*sizeof(uint32_t) | 100 | | mt19937 | 2^19937-1 | 625*sizeof(uint32_t) | 100 | | lagged_fibonacci607 | ок. 2^32000 | 607*sizeof(двойной) | 150 | | lagged_fibonacci1279 | ок. 2^67000 | 1279*sizeof(двойной) | 150 | | lagged_fibonacci2281 | ок. 2^120000 | 2281*sizeof(двойной) | 150 | | lagged_fibonacci3217 | ок. 2^170000 | 3217*sizeof(двойной) | 150 | | lagged_fibonacci4423 | ок. 2^230000 | 4423*sizeof(двойной) | 150 | | lagged_fibonacci9689 | ок. 2^510000 | 9689*sizeof(двойной) | 150 | | lagged_fibonacci19937 | ок. 2^1050000 | 19937*sizeof(двойной) | 150 | | lagged_fibonacci23209 | ок. 2^1200000 | 23209*sizeof(двойной) | 140 | | lagged_fibonacci44497 | ок. 2^2300000 | 44497*sizeof(двойной) | 60 | +-----------------------+-------------------+-----------------------------+------------------------+
длина цикла: длина последовательности случайных чисел до ее повторения
Там нет единого универсального RNG. Иногда важны статистические свойства, иногда криптология, иногда грубая скорость.