Congruentiegenerator

Uit testwiki
Versie door imported>Madyno op 21 mrt 2016 om 15:12
(wijz) ← Oudere versie | Huidige versie (wijz) | Nieuwere versie → (wijz)
Naar navigatie springen Naar zoeken springen

Een congruentiegenerator is een algoritme dat pseudotoevalsgetallen genereert, dat wil zeggen getallenrijen die deterministisch worden gegenereerd en dus niet echt willekeurig zijn, maar veel kenmerken van toevalsgetallen hebben. Congruentiegeneratoren zijn de bekendste en meestgebruikte pseudotoevalsgeneratoren.

Een congruentiegenerator wordt bepaald door de volgende parameters:

  • het aantal toestandswaarden n
  • de modulus m{2,3,4,}
  • de multipliers a1,,an{0,,m1}
  • de toename b{0,,m1}

en het algoritme waarmee een nieuw gegenereerd getal gegenereerd wordt voor i>n door de recurrente betrekking:

yi=k=1nakyik+b(modm).

Daarin zijn y1,,yn{0,,m1} de startwaarden.

Reële toevalsgetallen in het interval [0, 1] kunnen verkregen worden als ui=yi/m, mits m groot genoeg is om een voldoende nauwkeurige onderverdeling te geven.

De toestand van de generator voor de productie van yi wordt gegeven door de startwaarden. Deze toestand legt (voor gegeven n, m, k, b) alle volgende toevalsgetallen vast, omdat het volgende toevalsgetal en de volgende toestand door de huidige toestand bepaald worden. Er zijn mn mogelijke toestanden, en daarom moet er na maximaal mn stappen een eerdere toestand herhaald worden. De congruentiegenerator produceert dus een periodieke rij getallen, waarbij de lengte van de periode veel kleiner dan mn kan zijn. In extreme gevallen is de lengte 1, en zal de generator altijd hetzelfde "toevalsgetal" geven. Bij het kiezen van de parameters is het dus onder andere van belang om te zorgen voor een periode die lang genoeg is.

Lineaire congruentie

Als n=1, spreekt men van een lineaire-congruentiegenerator. Het algoritme is:

yi=ayi1+b(modm).

Is ook nog b=0, dus

yi=ayi1(modm),

dan is er sprake van een multiplicatieve-congruentiegenerator. De multiplicatieve congruentie heet ook Lehmer-congruentie, naar D. H. Lehmer die dit algoritme in 1949 introduceerde.

Fibonacci-generator

Een Fibonacci-generator is een congruentiegenerator met n=2, b=0 en a1=a2=1, en bestaat uit de volgende componenten:

  • Modulus m{2,3,4,}
  • Startwaarden y1,y2{0,,m1}

Met de volgende functie worden de pseudowillekeurige getallen gegenereerd:

yiyi1+yi2(modm)(met i3).

Een kenmerk is dat de gevallen yi1<yi+1<yi respectievelijk yi<yi+1<yi1 nooit voorkomen. Fibonacci-generatoren zijn dus niet geschikt als pseudotoevalsgenerator. Dit geldt met name voor wiskundige objecten waarvoor de productie van meer dan twee toevalsgetallen nodig is. Als men bijvoorbeeld probeert om een willekeurige wolk van punten in een kubus te genereren, dan zouden alle punten op twee vlakken liggen.

Vertraagde Fibonacci-generator

Het principe van de Fibonacci-generator kan worden gegeneraliseerd door niet de laatste twee, maar verder terug liggende waarden yi te gebruiken om een nieuw toevalsgetal te genereren. Dit resulteert in een vertraagde (Eng. 'lagged') Fibonacci-generator:

yiyiB+yiA(modm)metA,B+, A>B;i>A

met de startwaarden y1,,yA{0,,m1}.

Dan is n=A en aA=aB=1 en de andere ak zijn nul. Hierbij wordt m in het algemeen even gekozen en A en B worden gekozen, zodat de polynoom in x: xA+xB+1 een primitieve polynoom modulo 2 is. De periode van de generator is dan minimaal 2A1.

xA+xB+1 is een primitieve polynoom modulo 2 dan en slechts dan als xA+xAB+1 dat ook is. Zo kan men in plaats van B ook altijd AB berekenen.

De volgende tabel geeft enkele waarden voor A en B die aan deze voorwaarde voldoen:

A 2 31 55 73 98 100 135 258 607 3217 23209
B 1 13 24 25 27 37 22 83 273 576 9739

Deze generator wordt ook gebruikt in de praktijk. Het geeft echter niet altijd volledig willekeurige getallen. Het probleem van de gewone Fibonacci-generator is slechts verschoven; nu komen yiA<yi<yiB of yiB<yi<yiA nooit voor. Er zijn zelfs nog meer tekortkomingen.

Als oplossing werd voorgesteld om altijd alleen gebruikmaken van A opeenvolgende nummers, en dan de volgende 4A tot 10A getallen te verwerpen. Dit werkt goed, maar zorgt voor een 5 tot 11 keer hogere computatietijd. De door Donald Knuth voorgestelde generator ranarray werkt op deze manier. Hierbij is A=100 en B=37, en van 1009 opeenvolgende getallen wordt slechts een blok van 100 getallen gebruikt.

Om voor een periode van 2A1 te zorgen, is alleen de minst significante bit in de toestandswaarde yi van belang, dat wil zeggen, dat het van belang is of de bit even of oneven is. Het is mogelijk om de hogere orde bits naar behoefte te veranderen, om de kwaliteit van de resulterende toevalsgetallen te verbeteren. Bijvoorbeeld:

yiyiA+yiB+f(yiC)(modm);f:{0,,m1}{0,2,4,6,},C{1,,n}

Verdere veralgemening

Men kan de vertraagde Fibonacci-generator verder veralgemenen door meer dan twee toestandswaarden te verwerken:

yikMyik(modm)metM+.

Hier is n het grootste element in M. Om een periode van ten minste 2n1 te garanderen, moet ook hier de bijbehorende polynoom kMxk+1 of equivalent, de polynoom xn+kMxnk een primitieve polynoom modulo 2 zijn (met een even modulus m). Een generator die zo opgebouwd is met |M|>2 levert over het algemeen beter toevalsgetallen dan met |M|=2, maar ook dit gaat ten koste van de rekentijd.

Met een verdere generalisering kan voor een gegeven n de lengte van de periode verhoogd worden en waarschijnlijk ook de kwaliteit van willekeurige getallen verbeterd worden. p is een priemfactor van m. Voor de rekenregel

yik=1nakyik(modm)

zullen de ak{0,,m1}, met an≢0(modp), zodanig worden geselecteerd dat de polynoom in x

xnk=1nakxnk(modp)

een primitieve polynoom modulo p is. Dan is de periode ten minste pn1.

De vorige generator vloeit hieruit voort met p=2 en ak{0,1} als een bijzonder geval, en n=1; p=m levert een multiplicatieve congruentiegenerator met periode p1.

De polynoom f(x)=xnk=1nakxnk is een primitieve polynoom modulo p als

r=pn1p1 en a=(1)n1an

voldoen aan:

  • a is een primitief element modulo p
  • de polynoom xr is congruent aan a (modulo f(x))
  • voor alle priemfactoren q van r is de graad van de polynoom xr/q(mod )f(x) positief.

Hiervoor wordt polynoomrekening gebruikt en er wordt modulo p gerekend met de coëfficiënten (het zijn elementen van de quotiëntring /p).