program mlkgtest; { Verschiedene ZZ-Generatoren werden mittels RUN-Test analysiert. Zur Auswahl stehen - die eingebaute random-Funktion von TurboPascal 6.0 - ein MLKG mit der Periodenl„nge MaxLongInt ( vgl. Aufgabe ZZ-4 ! ) - ein MLKG mit den festen Parametern m=2311 und a=13 - ein MLKG mit im Rahmen des untersttzten Zahlenbereiches frei w„hlbaren Parametern Es werden jeweils soviel Folgeelemente (=Pseudo-Zufallszahlen) abgefordert, bis 100000 Run's realisiert sind. Es erfolgt keine Zwischenauswertung; nach jeweils 1000 Run's wird ein '*' ausgegeben. } uses crt; const no_of_runs = 100000; limit = 8; { fr Chiquadrattest; beobachtete RUN-L„ngen >= limit werden zu einer Klasse zusammengefaát } chiq :array[1..9] of real = (3.84,5.99,7.82,9.49,11.07,12.59,14.07,15.51,16.92); { Chiqudrat-Quantile aus Tabelle } glob:longint = 1; { Seed fr ZZ-Generator } var i,j,fak,no_zz:longint; a,m, actual_run, max_run:integer; x_alt,x_neu,chi,sum:real; run: array[1..limit] of longint; { Feld der beobachteten RUN's } th: array[1..limit] of real; { theoret. Run-H„ufigkeiten } my_choice : char; function mlkg(m,a,seed:integer):real; var k:longint; begin if seed<>0 then k:=seed else k:=glob; k:=k*a mod m; glob:=k; mlkg:=k/m; end; function rand_maxint : real; const a=16807; m=2147483647; { = 2^31 - 1 } q=127773; { m DIV a } r=2836; { m MOD a } var k:longint; begin k:= glob div q; glob:= a * (glob - k*q) - k*r; if glob < 0 then glob := glob + m; rand_maxint:= glob/m; end; function generator(typ:char) : real; begin case UpCase(typ) of '1','R': generator := random; '2','M': generator := rand_maxint; '3','B': generator := mlkg(2311,13,0); '4','C': generator := mlkg(m,a,0); end{case}; end; {main} begin clrscr; writeln('Bitte w„hlen Sie den Generator aus:'); writeln;writeln; writeln(' 1 --> normale random-Funktion'); writeln(' 2 --> MLKG mit maximaler Periode im longint-Bereich'); writeln(' 3 --> MLKG mit Periode 2311'); writeln(' 4 --> MLKG mit w„hlbaren Parametern'); writeln;writeln; repeat repeat until KeyPressed; my_choice := UpCase(ReadKey); until my_choice in ['1','2','3','4','B','C','R','M']; if my_choice in ['C','4'] then begin repeat write('Bitte Modul eingeben (<=32767) : '); read(m); until m <= maxint; repeat write('Bitte Multiplikator eingeben (<=',m:5,') : '); read(a); until a <= m; repeat write('Bitte Seed eingeben (<=',m:5,') : '); read(glob); until glob <= m; end; for i:=1 to limit do run[i]:=0; no_zz:=0; max_run:=0; for j:= 1 to no_of_runs do begin x_neu:=generator(my_choice); actual_run:=0; repeat inc(actual_run); x_alt:=x_neu; x_neu:=generator(my_choice) until (x_neu < x_alt); no_zz:=no_zz + actual_run + 1; if actual_run > max_run then max_run := actual_run; if actual_run > limit then actual_run := limit; run[actual_run] := run[actual_run] + 1; if ((j mod 1000) =0 ) then write('*'); end; clrscr; writeln(' RUN-Test fr Pseudo-Zufallszahlen, erzeugt mit MLKG ',my_choice); if my_choice in ['3','4'] then write(' a=',a:5,' m=',m:5); writeln; writeln('Anzahl der Runs :',no_of_runs:8); writeln('Generierte Zufallszahlen :', no_zz); writeln;writeln; writeln('RUN-L„nge empirische theoretische Summand fr'); writeln(' H„ufigkeit H„ufigkeit Chiquadrattest'); writeln('_______________________________________________________________'); writeln; chi:=0;fak:=1;sum:=0; for i:=1 to limit -1 do begin fak:=fak * (i+1); th[i]:= i/fak * no_of_runs; sum := sum + th[i] end; th[limit] := no_of_runs - sum; sum:=0; for i:= 1 to limit do begin chi:= (run[i] - th[i])*(run[i] - th[i])/th[i]; if i='); writeln(i:2,run[i]:15,th[i]:18:4,chi:15:4); sum := sum + chi end; writeln('___________________________________________________________'); writeln; writeln(' =',sum:11:4); writeln; writeln(' krit. Wert aus Chiquadrat-Tabelle =',chiq[limit-1]:11:2); writeln;writeln; writeln('Maximale Run-L„nge :',max_run:5); repeat until KeyPressed; end.