Компактные генераторы равномерного распределения случайных чисел Страница 3. Улучшенная версия генератора Парка-Миллера
|
Страница 3 из 4 Улучшенная версия генератора Парка-Миллера В дополнение к предыдущему алгоритму, производит перетасовку по методу Бейса и Дурхема, что позволяет уничтожить нежелательные корреляции между сериями сгенерированных случайных чисел. /* Минимальный компактный генератор случайных чисел Бейса-Дурхема */
/* Предыдущие фукнции и константы были описаны выше. */ #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, где он начинает повторяться. |