Frage

Wie berechne ich angesichts des Starts und des Ende eines Ganzzahl -Bereichs eine normal verteilte zufällige Ganzzahl zwischen diesem Bereich?

Mir ist klar, dass die Normalverteilung in -+ unendlich geht. Ich denke, die Schwänze können Cutoff sein. Wenn ein Zufall außerhalb des Bereichs berechnet wird, berechnen Sie sie erneut. Dies erhöht die Wahrscheinlichkeit von Ganzzahlen im Bereich, aber solange dieser Effekt tolerierbar ist (<5%), ist es in Ordnung.

public class Gaussian
{
    private static bool uselast = true;
    private static double next_gaussian = 0.0;
    private static Random random = new Random();

    public static double BoxMuller()
    {
        if (uselast) 
        { 
            uselast = false;
            return next_gaussian;
        }
        else
        {
            double v1, v2, s;
            do
            {
                v1 = 2.0 * random.NextDouble() - 1.0;
                v2 = 2.0 * random.NextDouble() - 1.0;
                s = v1 * v1 + v2 * v2;
            } while (s >= 1.0 || s == 0);

            s = System.Math.Sqrt((-2.0 * System.Math.Log(s)) / s);

            next_gaussian = v2 * s;
            uselast = true;
            return v1 * s;
        }
    }

    public static double BoxMuller(double mean, double standard_deviation)
    {
        return mean + BoxMuller() * standard_deviation;
    }

    public static int Next(int min, int max)
    {
        return (int)BoxMuller(min + (max - min) / 2.0, 1.0); 
    }
}

Ich muss wahrscheinlich die Standardabweichung wie relativ zum Bereich skalieren, aber nicht verstehen, wie.

Antworten:

    // Will approximitely give a random gaussian integer between min and max so that min and max are at
    // 3.5 deviations from the mean (half-way of min and max).
    public static int Next(int min, int max)
    {
        double deviations = 3.5;
        int r;
        while ((r = (int)BoxMuller(min + (max - min) / 2.0, (max - min) / 2.0 / deviations)) > max || r < min)
        {
        }

        return r;
    }
War es hilfreich?

Lösung

Wenn die Box-Müller-Methode eine "Standard" -Normalverteilung zurückgibt, hat sie Mittelwert von 0 und Standardabweichung 1. Um eine Standardnormalverteilung zu transformieren, multiplizieren Sie Ihre Zufallszahl mit X, um die Standardabweichung x zu erhalten. meine y, wenn die Erinnerung mir richtig dient.

Siehe das Abschnitt des Wikipedia -Artikels zur Normalisierung der normalen Normalvariablen (Eigenschaft 1) für einen formelleren Beweis.


Als Antwort auf Ihren Kommentar lautet die Faustregel, dass 99,7% einer Normalverteilung innerhalb der +/- 3-fachen der Standardabweichung liegen. Wenn Sie beispielsweise eine Normalverteilung von 0 bis 100 benötigen, ist Ihr Mittelwert zur Hälfte und Ihr SD (100/2)/3 = 16,667. Also, welche Werte Sie also aus Ihrem Box-Muller-Algorithmus erhalten, multiplizieren Sie mit 16.667, um die Verteilung auszudehnen, und fügen Sie dann 50 zu "Zentrum" hinzu.


John, als Antwort auf Ihren neuesten Kommentar bin ich mir wirklich nicht sicher Next Funktion. Es verwendet immer eine Standardabweichung von 1 und einen Mittelwert der Hälfte zwischen Ihrem Min und Max.

Wenn Sie einen Mittelwert von y mit ~ 99,7% der Zahlen im Bereich -x bis +x wollen, rufen Sie nur an BoxMuller(Y, X/3).

Andere Tipps

Nun, das -2*Sigma ..+2*Sigma gibt Ihnen 95% der Glockenkurve. (Überprüfen Sie den Abschnitt "Standardabweichung und Konfidenzintervalle" im bereits erwähnten Wiki -Artikel).

Ändern Sie dieses Stück also:

return (int)BoxMuller(min + (max - min) / 2.0, 1.0);

und ändern Sie 1.0 (Standardabweichung) auf 2.0 (oder sogar mehr, wenn Sie mehr als 95% Abdeckung wünschen)

return (int)BoxMuller(min + (max - min) / 2.0, 2.0);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top