Generieren Sie eine Zufallszahl mit max, min und mittlerem (Durchschnitt) in Java
Frage
Ich muss zufällige Zahlen mit folgenden Eigenschaften generieren.
Min sollte 200 sein
Max sollte 20000 sein
Durchschnittlich (Mittelwert) beträgt 500.
Optional: 75. Perzentil zu 5000 sein
Auf jeden Fall ist es weder eine einheitliche Verteilung noch Gauß. Ich muss ein paar linke Schiefe geben.
Lösung
Java Random wird wahrscheinlich nicht funktionieren, da es Ihnen nur normale (Gaußsche) Verteilungen gibt.
Was Sie wahrscheinlich suchen, ist eine F -Verteilung (siehe unten). Sie können wahrscheinlich die Distlib -Bibliothek verwenden hier und wählen Sie die F Verteilung. Du kannst den ... benutzen zufällig Methode, um Ihre Zufallszahl zu erhalten.
Andere Tipps
Sagen X
Ist Ihre Zielvariable, normalisieren Sie den Bereich durch, indem Sie dies tun Y=(X-200)/(20000-200)
. Also willst du etwas Y
zufällige Variable, die Werte in nimmt [0,1]
mit gemein (500-200)/(20000-200)=1/66
.
Sie haben viele Möglichkeiten, die natürlichste scheint mir a Beta -Verteilung, Y ~ Beta(a,b)
mit a/(a+b) = 1/66
- Sie haben einen zusätzlichen Freiheitsgrad, den Sie entweder für die letzte Quartilanforderung entscheiden können.
Danach geben Sie einfach x als zurück als Y*(20000-200)+200
Um eine Beta -Zufallsvariable zu generieren, können Sie verwenden Apache Commons oder sehen hier.
Dies ist möglicherweise nicht die Antwort, nach der Sie suchen, aber der spezifische Fall mit 3 einheitlichen Verteilungen:
(Ignorieren Sie die Zahlen links, aber es ist zu skalieren!)
public int generate() {
if(random(0, 65) == 0) {
// 50-100 percentile
if(random(1, 13) > 3) {
// 50-75 percentile
return random(500, 5000);
} else {
// 75-100 percentile
return random(5000, 20000);
}
} else {
// 0-50 percentile
return random(200, 500);
}
}
Wie ich die Zahlen bekam
Erstens ist die Fläche unter der Kurve zwischen 200-500 und 500-20000. Dies bedeutet, dass die Höhenbeziehung ist 300 * leftHeight == 19500 * rightHeight
Herstellung leftHeight == 65 * rightHeight
Dies gibt uns eine 1/66 Chance, rechts auszuwählen, und eine 65/66 Chance, links auszuwählen.
Ich habe dann die gleiche Berechnung für das 75. Perzentil durchgeführt, außer dass das Verhältnis war 500-5000 chance == 5000-20000 chance * 10 / 3
. Auch dies bedeutet, dass wir eine 10/13 Chance haben, in 50-75 Prozent und eine 3/13 Chance in 75-100 zu sein.
Ein großes Lob an @Stas - Ich benutze seine 'inklusive zufällige' Funktion.
Und ja, ich merke, dass meine Zahlen falsch sind, da diese Methode mit diskreten Zahlen funktioniert und meine Berechnungen kontinuierlich waren. Es wäre gut, wenn jemand meine Grenzfälle korrigieren könnte.
Sie können eine Funktion f haben, die an [0; 1] wie z.
Integral(f(x)dx) on [0;1] = 500
f(0) = 200
f(0.75) = 5000
f(1) = 20000
Ich denke eine Funktion der Form
f(x) = a*exp(x) + b*x + c
Könnte eine Lösung sein, Sie müssen nur das verwandte System lösen.
Dann tust du es f(uniform_random(0,1))
Und da bist du!
Das PERT -Verteilung (oder Beta-PERT-Verteilung) ist so konzipiert, dass er einen minimalen und maximalen und geschätzten Modus einnimmt. Es handelt sich um eine "geglättete" Version der dreieckigen Verteilung, und es kann wie folgt implementiert werden, eine zufällige Zahl aus dieser Verteilung zu generieren:
startpt + (endpt - startpt) *
BetaDist(1.0 + (midpt - startpt) * shape / (endpt - startpt),
1.0 + (endpt - midpt) * shape / (endpt - startpt))
wo-
startpt
ist das Minimum,midpt
ist der Modus (nicht unbedingt durchschnittlich oder Mittel),endpt
ist das Maximum,shape
ist eine Zahl 0 oder größer, aber normalerweise 4, undBetaDist(X, Y)
Gibt eine Zufallszahl aus der Beta -Verteilung mit Parametern zurückX
undY
.
Mit einem bekannten Mittel (mean
), midpt
kann berechnet werden durch:
3 * mean / 2 - (startpt + endpt) / 4