Страница 27 из 37
Использование нескольких генераторов Один простой метод, который улучшает свойства случайных пос- ледовательностей, порождаемых тремя генераторами, заключается в комбинировании их под управлением одной главной функции. Данная функция выбирает между двумя из них, основываясь на результате третьей. С помощью этого метода вы можете получить очень длинный период и уменьшить влияние циклов и смещений. Функция, называемая CombRandom, показанная здесь, осуществляет комбинирование выводов генераторов Ran1, Ran2, Random:
{данная функция использует три генератора для возврата одного случайного числа } function CombRandom: real; var f: real;
begin f := Ran2; if f>0.5 thenCombRandom := Random else CombRandom := Ran1; { случайный выбор генератора } end; {CombRandom}
Результат Ran2 используется для того, чтобы решить, Ran1 или Random выдаст значение главной функции CombRandom. При таком ме- тоде период главной функции равен или больше суммы периодов Random и Ran1. Таким образом, данный метод делает возможным по- рождение последовательности с очень длинным периодом. Можно легко изменять смесь Random и Ran1 изменением константы в операторе if, чтобы получить желаемое вами распределение между этими двумя ге- нераторами. Кроме того, вы можете добавить дополнительные генера- торы и осуществлять выбор между ними для получения еще более длинного периода. Далее следует программа для отображения диаграммы CompRandom и ее среднего значения. На рис.7-3 показана финальная диаграмма после генерации 1000 чисел. Среднее значение CombRandom равно 0,493361.
{ данная программа демонстрирует комбинированный вывод трех генераторов случайных чисел } program MultiRandom;
uses Graph; const
COUNT=1000;
var freg: array[0..9] of integer; a2,a1: integer; f, r: real; y, x: integer; GraphDriver, GraphMode: integer;
{ отображение графического представления работы генераторов } procedure Display; var t: integer;
begin for t := 0 to 9 do Line(t*10+110, 180, t*10+110, 180-freg[t]); end; {Display}
function Ran1: real; var t: real; begin t := (a1*32749+3) mod 32749; a1 := Trunc(t); Ran1 := Abs(t/32749); end; {Ran1}
function Ran2: real; var t: real; begin t := (a2*10001+3) mod 17417; a2 := Trunc(t); Ran2 := Abs(t/17417); end; {Ran2}
{данная функция использует три генератора для возврата одного случайного числа } function CombRandom real; var t: real;
begin f := Ran2; if f>0.5 then CombRandom := Random else CombRandom := Ran1; {случайный выбор генератора } end; {CombRandom} begin { переключение на графический режим, используя режим 4 CGA/EGA } GraphDriver := CGA; GraphMode := CGAC1; InitGraph(GraphDriver, GraphMode, ''); SetColor(2); SetLineStyle(SolidLn, 0, NormWidth);
OutTextXy(48, 10, 'вывод, полученный комбинированием '); OutTextXy(40,20, 'три генератора случайных чисел '); Line(110, 180, 200, 180);
a1:=1; a2:=203; {инициализация переменных для генераторов случайных чисел } f := 0;
for x:=0 to 9 do freg[x]:=0; {инициализация матрицы частот}
for x := 1 to COUNT do begin r:=CombRandom; { взять случайное число } f:=f+1; { прибавить для вычисления среднего } y:=Trunc(r*10);{ преобразовать в целое число от 0 до 9} freg[y]:=freg[y]+1;{ увеличить счетчик частоты } Display; end; ReadLn; RestoreCrtMode; WriteLn('Среднее случайное число равно : ', f/COUNT); end.
----------------------------------------------------- Вывод, полученный комбинированием трех генераторов случай- ных чисел. ¦ ¦ ¦ ¦ ¦ ¦ ¦¦¦¦¦¦¦¦¦¦ ¦¦¦¦¦¦¦¦¦¦ ¦¦¦¦¦¦¦¦¦¦ ¦¦¦¦¦¦¦¦¦¦ ¦¦¦¦¦¦¦¦¦¦ L++++++++- ------------------------------------------------------
Рис.7-3. Финальное отображение функции CombRandom:
|