Comment puis-je convertir une distribution uniforme (comme la plupart des générateurs de nombres aléatoires produire, par exemple, entre 0.0 et 1.0) dans une distribution normale? Que faire si je veux une moyenne et écart-type de mon choix?
Réponses
Trop de publicités?Il ya beaucoup de méthodes:
- Ne pas utiliser la Boîte de Muller. Surtout si vous attirent de nombreux gaussien numéros. Boîte de Muller donne un résultat qui est fixée entre -6 et 6 (en supposant que la double précision. Les choses s'aggravent avec des flotteurs.). Et c'est vraiment moins efficace que les autres méthodes disponibles.
- Ziggourat est bien, mais a besoin d'une table de recherche (et certains sont spécifiques à la plateforme de peaufinage en raison de la taille du cache de questions)
- Rapport de l'uniforme est mon préféré, seulement un peu plus/de multiplications et d'un log 1/50e du temps (par exemple. regardez-là).
- L'inversion de la CDF est efficace (et négligé, pourquoi ?), vous avez rapidement mises en œuvre de la disposition si vous effectuez une recherche google. Elle est obligatoire pour la Quasi-Aléatoire de nombres.
La Ziggourat de l'algorithme est assez efficace pour ce, bien que le Box-Muller transformer est plus facile à mettre en œuvre à partir de zéro (et pas fou lent).
La modification de la distribution de n'importe quelle fonction à l'autre implique l'utilisation de l'inverse de la fonction de probabilité que vous voulez.
En d'autres termes, si vous savez que la fonction de probabilité p(x) et il a un inverse: Inv(p(x)), puis en utilisant l'aléatoire de fonction de probabilité (distribution uniforme) et le casting du résultat de la valeur grâce à la fonction Inv(p(x)), vous devriez obtenir des valeurs aléatoires de fonte avec la répartition selon la fonction que vous voulais, maintenant, c'est seulement une question de choisir votre choix de probabilité de la fonction et son inverse.
Espérons que cela a aidé et que je n'ai pas mélangé mes maths :)
Voici un javascript mise en œuvre à l'aide de la forme polaire de Box-Muller transformation.
/*
* Returns member of set with a given mean and standard deviation
* mean: mean
* standard deviation: std_dev
*/
function createMemberInNormalDistribution(mean,std_dev){
return mean + (gaussRandom()*std_dev);
}
/*
* Returns random number in normal distribution centering on 0.
* ~95% of numbers returned should fall between -2 and 2
*/
function gaussRandom() {
var u = 2*Math.random()-1;
var v = 2*Math.random()-1;
var r = u*u + v*v;
/*if outside interval [0,1] start over*/
if(r == 0 || r > 1) return gaussRandom();
var c = Math.sqrt(-2*Math.log(r)/r);
return u*c;
/* todo: optimize this algorithm by caching (v*c)
* and returning next time gaussRandom() is called.
* left out for simplicity */
}
Java est au Hasard de classe a de la nextGaussian() méthode pour cela.