Inverser Kongruenzgenerator

Aus testwiki
Zur Navigation springen Zur Suche springen

Ein inverser Kongruenzgenerator ist ein arithmetischer Zufallszahlengenerator, der durch den Satz von Marsaglia bekannte Nachteile linearer Kongruenzgeneratoren vermeidet. Insbesondere lässt er keine Hyperebenen entstehen. Verwendet man Zufallszahlen inverser Kongruenzgeneratoren für die Box-Muller-Methode, so wird ein Spiralverhalten vermieden. Im Gegenzug verlangt er einen höheren Rechenaufwand.

Allgemeines

Er besteht aus folgenden Komponenten:

  • Modul p ( steht hierbei wie üblich für die Menge der Primzahlen)
  • Faktor a{0,...,p1}
  • Inkrement b{0,...,p1}
  • Startwert y0{0,...,p1}

Der Generator arbeitet nach folgendem Bildungsgesetz:

yn+1=(ayn1+b)modp=(aynp2+b)modp

Zur Erklärung der Symbolik siehe den Artikel Modulo.

Wegen p gibt es zu jedem yn0 ein eindeutiges multiplikativ inverses Element yn1, so dass ynyn11. Nur für yn=0 muss man sich noch Gedanken machen. Rein formal wäre das inverse Element von 0. Da nicht darstellbar ist, wird es am besten übersprungen, indem man 01=0 setzt, wie es auch der zweiten Darstellung (mit ynp2) entspricht.

Periodenlänge

Die maximale Periodenlänge kann offenbar p nicht überschreiten. Erreicht wird diese genau dann, wenn das Polynom

x2bxa

ein primitives Polynom in p ist.

Hyperebenenverhalten

Im Gegensatz zu linearen Kongruenzgeneratoren, deren Werte ja auf wenigen Hyperebenen liegen, kann man hier zeigen, dass gilt:

Jede Hyperebene in pk enthält maximal k Punkte der Form
(x1,,xk),(x2,,xk+1),
solange xlxl+k20 gilt. Durch diese Bedingung scheiden genau k1 Punkte aus. Dabei ist k2 beliebig wählbar.

Inverse Generatoren mit zusammengesetztem Modul

Um die Modulodivision durch das Abschneiden der höchstwertigen Bits ersetzen zu können, wäre es angenehm, Moduln m für die Berechnungsvorschrift

yn+1=(aynp2+b)modm

zuzulassen, die keine Primzahl, sondern eine Potenz von 2 sind. Dazu muss y0 ungerade sein, und a,b müssen so festgelegt werden, dass alle yn ungerade sind, denn dann kann das inverse Element zu yn eindeutig berechnet werden. Die Periodenlänge beträgt höchstens m/2. Falls folgende Bedingungen erfüllt sind, beträgt sie genau m/2:

  • m=2emite3
  • a1(mod4)
  • b2(mod4)

Programmierung

Das folgende Programm in der Programmiersprache C++ zeigt die Implementierung eines inversen Kongruenzgenerators mit

p=21269

,

a=8

und

b=3

. Es erzeugt 10 Zufallszahlen, die in einem Array gespeichert werden. Das multiplikativ inverse Element von

yn

modulo

p

wird mit dem erweiterten euklidischen Algorithmus bestimmt. Bei der Ausführung des Programms wird die Hauptfunktion main verwendet, die die Zufallszahlen auf der Konsole ausgibt.

#include <iostream>
using namespace std;

// Diese Funktion bestimmt das multiplikative Inverse von a modulo b mithilfe des erweiterten euklidischen Algorithmus
int getModularMultiplicativeInverse(int a, int b)
{
    if (a == 0)
    {
        return 0; // Spezialfall: Inverses von 0
    }
    int d = 1; // Deklaration der lokalen Variablen
    int t = 0;
    int u = 0;
    int v = 1;
    while (b != 0)
    {
        int q = a / b;
        int b1 = b; // Variable zum Zwischenspeichern
        b = a - q * b;
        a = b1;
        int u1 = u; // Variable zum Zwischenspeichern
        u = d - q * u;
        d = u1;
    }
    return d;
}

// Funktion, die die Zufallszahlen erzeugt
int* inversiveCongruentialGenerator(int y0, int p, int a, int b, int count)
{
    int* randomNumbers = new int[count]; // Initialisiert das Array für die Zufallszahlen
    randomNumbers[0] = y0; // Startwert für den Zufallszahlengenerator
    for (int i = 0; i < count; i++)
    {
        randomNumbers[i] = (a * getModularMultiplicativeInverse(randomNumbers[i - 1], p) + b) % p;
    }
    return randomNumbers;
}

// Hauptfunktion die das Programm ausführt
int main()
{
    int y0 = 0; // Deklaration der lokalen Variablen
    int p = 21269;
    int a = 8;
    int b = 3;
    int count = 10;
    int* randomNumbers = inversiveCongruentialGenerator(y0, p, a, b, count); // Aufruf der Funktion
    for (int i = 0; i < count; i++)
    {
        cout << randomNumbers[i] << endl; // Ausgabe auf der Konsole
    }
}

Explizite inverse Generatoren

Manchmal liest man auch die Definition

yn+1=(an+b)1modp=(an+b)p2modp

oder auch

yn+1=(a(n+y0)+b)1modp=(a(n+y0)+b)p2modp

Letzteres stellt keine Verallgemeinerung dar; man erhält durch Ausmultiplizieren sofort die obige Gestalt.

Periodenlänge

Die maximale Periodenlänge beträgt wieder p und wird erreicht, falls a0 gilt.

Siehe auch

Literatur

  • Harald Niederreiter: Random Number Generation and Quasi-Monte Carlo Methods. Society for Industrial & Applied Mathematics, Philadelphia PA 1992, ISBN 0-89871-295-5 (Regional Conference Series in Applied Mathematics 63).