Hallo,
Also etwa so:
[php]
$randval = getRandBetweenMinMaxWithAverage(0, 3, 0.5);function getRandBetweenMinMaxWithAverage($min, $max, $avg){
//do something
return $randval;
}
[/php]Wie kann ich jetzt berechnen, wie häufig die einzelnen Werte 0 bis 3 vorkommen müssen
damit der Durchschnittswert 0,5 erreicht wird?
Du brauchst zunächst mal eine Verteilungsfunktion f(x)
für x-Werte zwischen 0 und 3. Diese muss folgende
Bedingungen erfüllen:
a) Das Integral zwischen x=0...3 über f(x) muss 1 ergeben (Normierung).
b) Das Integral von x*f(x) zwischen 0..3 soll 0.5 ergeben,
das ist dann der gewünschte Schwerpunkt der Verteilung.
Da es beliebig viele Möglichkeiten gibt, sich eine
Funktion für x=0...3 auszudenken, nimmt man einen
sinnvoll aussehenden Ansatz mit einer überschaubaren
Anzahl von Variablen, z. B.
f(x) = A*exp(-B*x)
Diese Funktion hat den Vorteil, dass sie im unteren
Bereich von 0...3 die größeren Werte hat (für positive A,B),
so dass der Schwerpunkt ebenfalls im unteren Bereich liegen sollte.
Die Bedingungen a) und b) führen leider
auf Gleichungen, die nur numerisch lösbar sind.
Falls Du stattdessen einen Polynom-Ansatz
nimmst, geht es evtl. besser.
Für das Intervall [0..3] und den Schwerpunkt 0.5
zeige ich mal folgendes Beispiel per cut&paste
(allerdings nicht in PHP...):
=====8><==========================================================
$ cat verteilung.r
#!/usr/local/bin/rvm
float x=3,
A=1, B=1,
f->A*exp(-B*x), # Verteilungsfunktion
F->A/B * (1-exp(-B*x)), # Normierung
M->-A/B*x*exp(-B*x) + A/B^2*(1-exp(-B*x)); # Schwerpunkts-
# Integral
Fit_MRQ X = {
parameters->[A,B];
equations = [
{ left -> F; right -> 1; }, # Norm soll 1 ergeben
{ left -> M; right -> 0.5; } # Schwerpunkt soll 0.5 ergeben
];
};
out "A = $X.A, B = $X.B\n";
$ rvm verteilung.r
A = 1.97306, B = 1.96767
=====8><==========================================================
Mit diesen Werten musst Du nun die Stammfunktion
F(x) = A/B*(1-exp(-B*x)) nehmen, diese mit einer
Zufallsfunktion random() gleichsetzen, die zwischen
0...1 gleichverteilt ist und das ganze nach x auflösen.
Ich komme auf folgendes Ziehungsverfahren (ohne Gewähr...):
x = -1/B * ln(1-B*random()/A)
Mit obigen Parametern für A und B liegen die
gezogenen X-Werte dann zwischen 0...3 und haben
den Schwerpunkt 0.5 - vorausgesetzt, dass der
Zufallsgenerator in random() gleichverteilte
Zahlen zwischen 0...1 liefert.
Viele Grüße
Andreas Pflug