Comment générer normalement distribuées de façon aléatoire à partir d'un nombre entier de gamme?
Donné le départ et la fin d'un intervalle entier, comment dois-je calculer une distribution normale entier aléatoire entre cette gamme?
Je me rends compte que la distribution normale va en+ l'infini. Je suppose que les queues peuvent être de coupure, de sorte que, lorsqu'un hasard obtient calculée en dehors de la plage, recalculer. Cela élève la probabilité d'entiers dans la gamme, mais tant que cet effet est tolérable (<5%), c'est la fin.
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);
}
}
J'ai probablement besoin à l'échelle de l'écart-type d'une façon relative par rapport à la plage, mais ne comprennent pas comment.
Réponse:
//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;
}
OriginalL'auteur | 2009-08-20
Vous devez vous connecter pour publier un commentaire.
Si la méthode de Box-Muller retourne un "standard" de la distribution normale, il aura de moyenne 0 et d'écart type 1. Pour transformer une distribution normale standard, vous multipliez votre nombre aléatoire par X pour obtenir l'écart type de X, et vous Y ajouter pour obtenir la moyenne de Y, si ma mémoire est bonne.
Voir le Article de wikipédia sur les normaliser normal variables (propriété 1) pour plus de preuve formelle.
En réponse à votre commentaire, la règle de base est que 99,7% de la distribution normale sera à l'intérieur de +/- 3 fois l'écart-type. Si vous avez besoin d'une distribution normale de 0 à 100 par exemple, que votre moyenne sera à mi-chemin, et votre SD (100/2)/3 = 16.667 pour. Donc, quelles que soient les valeurs que vous sortez de votre Box-Muller algorithme, il faut multiplier par 16.667 pour "étirer" la distribution, puis ajouter 50 pour "centrer".
John, en réponse à ta dernière remarque, je ne suis vraiment pas sûr de ce qui est le point de la
Next
fonction. Il utilise toujours un écart type de 1 et une moyenne d'à mi-chemin entre votre min et max.Si vous voulez une moyenne de Y, ~99,7% des nombres de la plage -X +X, puis vous appelez
BoxMuller(Y, X/3)
.Donc, pour 3,5 écarts-types, il serait "return (int)BoxMuller(min + (max - min) / 2.0, (max - min) / 2.0 / 3.5);"?
Puis-je juste un commentaire que +/- 3 fois l'écart type vous donne pas 97% mais de 99,7%. +/-sigma: ~68% +/-2sigma: ~95% +/-3sigma: ~99.7% en.wikipedia.org/wiki/68-95-99.7_rule
Merci pour cette remarque, Dmitry -- mes statistiques sont un peu rouillé, apparemment. J'ai mis à jour la réponse.
OriginalL'auteur Mark Rushakoff
Bien, l'-2*sigma..+2*sigma va vous donner 95% de la courbe en cloche.
(cocher la case "écart-type et l'intervalle de confiance" dans la section déjà mentionné l'article wiki).
Donc modifier cette pièce:
et changement 1.0 (écart-type) 2.0 (ou même plus si vous voulez plus de 95% de couverture)
Ah, je comprends maintenant. Donc, vous voulez sortir de votre valeur moyenne de droite et de gauche et de "hit", soit min ou max avec une confiance de 95%. Dans ce cas, vous gardez vos dire que vous l'avez (min + (max-min)/2), mais vous avez besoin pour calculer votre sigma (écart-type). Sortir par 2*sigma nous donne que plus de 95% de l'intervalle. De sorte que la longueur de cet intervalle est de 4*sigma. Mais on peut aussi calculer sous la forme (max-min). Ce qui nous donne sigma=(max-min)/4. Pouvez-vous s'il vous plaît essayer?
"hit" dans la min..max de la gamme avec 95% de confiance - juste pour être précis dans ma formulation.
Cela fonctionne aussi, dommage que je ne peut faire qu'une seule réponse correcte. Stackoverflow devrait ajouter "assisté" ou "partagé" des réponses.
OriginalL'auteur DmitryK