Сборник по задачам и примерам Assembler


Смешанный конгруэнтный метод генерации последовательности случайных чисел



Смешанный конгруэнтный метод генерации последовательности случайных чисел

Соотношение смешанного конгруэнтного метода выглядит так: Xn+1=(aXn+c) mod m, где n > 0.

При правильном подборе начальных значений элементов кроме увеличения периода последовательности случайных чисел уменьшается корреляция (зависимость) получаемых случайных чисел.

На значения накладываются ограничения:

  • Х0>0;
  • а=21+1, где 1>=2;
  • с>0 взаимно просто с m (это выполнимо, если с — нечетно, а т=2р, где (р>=2)
  • m=2р (р>=2) и т кратно 4.

:rand_mix_cong_l.asm - датчик линейной (смешанной)

:конгруэнтной последовательности случайных чисел (с>0).

:Вход: Хо. а. с. m - в соответствии с указанными выше

ограничениями.

:Выход: dl - значение очередного случайного числа.

.data

m db 128 ; 128=27

a db 9

х db 3 начальное значение

с dw 3

.code

mov cl.7 :значение степени m=27 в cl ;первое число в последовательности х=3 cycl: вычисляем очередное случайное число Х=(а*Х) mod m

mov al.x

mul a :a*x в ah:al

add ax,с

shrd ax.ax.cl

xor al.al

rol ax.cl :b al случайное число :вывод в файл - командная строка rand_mult_cong.exe > p.txt

end_cycl:

Величина периода случайной последовательности, получаемой с помощью данной программы, составляет 128 значений. Сегмент кода программы rand_mix_ cong_1.asm можно оформить в виде процедуры. Начальное значение Хо можно выбирать двумя способами: задавать константой в программе или генерировать случайным образом. В последнем случае можно использовать такты системного таймера, как в следующей макрокоманде:

rCMOS macro

макрокоманда чтения значений CMOS

:на входе: al адрес ячейки, значение которой читаем

:на входе-выходе: al - прочтенное значение

out 70h,al

хог ах,ах :вводим в регистр AL из порта значение ячейки cmos

in al.71h

endm .code

:получить значение секунд из CMOS для x_start mov al.00 rCMOS mov x.al :x=x_start

Таким способом можно получить начальное значение из диапазона 0..59. Для получения большего по величине начального значения можно использовать величину размером 32 бита из области данных BIOS по адресу 0040:006с. Здесь содержится счетчик прерываний от таймера. Извлечь это значение можно, используя следующий программный фрагмент:

push ds

push 40h

pop ds

mov eax.dword ptr ds:006ch

popds

Заменяя команду MOV командами MOV AX,word ptr ds:006ch или MOV AL, byte ptr ds:006ch, можно использовать младшие 8 или 16 бит значения из этой области BIOS. Команда MOV AL, byte ptr ds:006ch позволяет случайным образом получить в регистре AL значение из диапазона 00.. f fh.

Попытки создать программный датчик случайных чисел без опоры на какую-либо теорию обречены на провал. Рассмотрим еще несколько способов генерации случайных чисел.




- Начало -  - Назад -  - Вперед -