Сборник по задачам и примерам 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.

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



    Содержание раздела