Компактные генераторы равномерного распределения случайных чисел
Страница 3. Улучшенная версия генератора Парка-Миллера


 

Улучшенная версия генератора Парка-Миллера

В дополнение к предыдущему алгоритму, производит перетасовку по методу Бейса и Дурхема, что позволяет уничтожить нежелательные корреляции между сериями сгенерированных случайных чисел.

/* Минимальный компактный генератор случайных чисел Бейса-Дурхема */

/* Предыдущие фукнции и константы были описаны выше. */
#define NTAB 32
#define NWUP 8
#define NDIV (1+(IM-1)/NTAB)
#define EPS 1.2e-7
#define RNMX (1.0-EPS)

float unirand1(void) {
int j;
long k;
static long iy=0,iv[NTAB];
float temp;
/* инициализация */
if(dummy<=0 || !iy) {
/* следим, чтобы значение было положительным */
if(dummy<0) dummy=-dummy;
else if(dummy==0) dummy=1;
for(j=NTAB+NWUP-1;j>=0;j--) {
k=dummy/IQ;
if((dummy=IA*(dummy-k*IQ)-IR*k)<0) dummy+=IM;
if(j<NTAB) iv[j]=dummy;
}
/* первый элемент из таблицы */
iy=iv[0];
}
/* генерируем новое число */
k=dummy/IQ;
if((dummy=IA*(dummy-k*IQ)-IR*k)<0) dummy+=IM;
iy=iv[j=iy/NDIV];iv[j]=dummy;
if((temp=AM*iy)>RNMX) return(RNMX);
else return(temp);
}

Маска здесь не применяется, так как метод инициализации алгоритма отсекает ошибочные значения текущего счетчика.

Алгоритм Парка-Миллера с перетасовкой проходит все известные тесты, включая и те, где без перетасовки этот алгоритм дает сбой. Хорошее поведение наблюдается до значений числа вызовов счетчика порядка 10^8, где он начинает повторяться.

 
« Предыдущая статья   Следующая статья »