Przejdź do treści

normal distribution

Generator liczb pseudolosowych (cz.2) – rozkład normalny

  • przez

W poprzednim odcinku otrzymaliśmy całkiem przyzwoity generator liczb o rozkładzie równomiernym. Teraz uzupełnimy naszą klasę o metodę do pobierania wartości z rozkładu normalnego, zwanego też rozkładem Gaussa.

Zastosowanym algorytmem do generowania liczb losowych z rozkładu normalnego jest implementacja metody Kindermana i Monahana, zwanej ROU (ratio-of-uniforms method). Szczegóły tej metody można znaleźć w książce Wieczorkowskiego i Zielińskiego[2]

Moja implementacja w języku C++ zawarta jest w metodzie getFromNormalDistribution() klasy RandomNumberGenerator i wygląda następująco:

double RandomNumberGenerator::getFromNormalDistribution() {

    bool ok = false;
    double limit = sqrt(2/2.718281828);
    double X;

    do {
        // generuj U o rozkładzie równomiernym U(0,1)
        double U = getFromUniformDistribution();

        // generuj V o rozkładzie równomiernym
        // U(-sqrt(2/e),sqrt(2/e))

        double V = 2 * limit * getFromUniformDistribution() - limit;
        X = V / U;

        if (X*X <= 2*(3-U*(4+U))) {

            ok = true;

        } else if (X*X <= 2/U - 2*U) {

            if (X*X <= -4*log(U)) {
               ok = true;
            }

        }
    } while (!ok);

    return X;
}

Jak widać używa on metody getFromUniformDistribution() zdefiniowanej wcześniej a zwracającej nam dwie liczby z rozkładu równomiernego, jedna z przedziału (0,1) a druga z (-sqrt(2/e), sqrt(2/e)).

Czytaj dalej »Generator liczb pseudolosowych (cz.2) – rozkład normalny