La mise en œuvre de Fort-Mueller générateur de nombres aléatoires en C#
De cette question: générateur de nombre Aléatoire qui gravite chiffres à un nombre donné dans la gamme? j'ai fait quelques recherches depuis que je suis arrivé sur un générateur de nombre aléatoire avant. Je me souviens, a été le nom "Müller", donc je suppose que je l'ai trouvé, ici:
Je peut trouver de nombreuses applications dans d'autres langues, mais je n'arrive pas à le mettre en œuvre correctement en C#.
Cette page, par exemple, La Méthode de Box-Muller pour la Génération de Nombres Aléatoires Gaussiennes dit que le code devrait ressembler à ceci (ce n'est pas C#):
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
double gaussian(void)
{
static double v, fac;
static int phase = 0;
double S, Z, U1, U2, u;
if (phase)
Z = v * fac;
else
{
do
{
U1 = (double)rand() / RAND_MAX;
U2 = (double)rand() / RAND_MAX;
u = 2. * U1 - 1.;
v = 2. * U2 - 1.;
S = u * u + v * v;
} while (S >= 1);
fac = sqrt (-2. * log(S) / S);
Z = u * fac;
}
phase = 1 - phase;
return Z;
}
Maintenant, voici ma mise en œuvre de la ci-dessus en C#. Notez que le transformer en produit de 2 nombres, d'où l'astuce de la "phase" ci-dessus. J'ai simplement jeter la deuxième valeur, et de retour de la première.
public static double NextGaussianDouble(this Random r)
{
double u, v, S;
do
{
u = 2.0 * r.NextDouble() - 1.0;
v = 2.0 * r.NextDouble() - 1.0;
S = u * u + v * v;
}
while (S >= 1.0);
double fac = Math.Sqrt(-2.0 * Math.Log(S) / S);
return u * fac;
}
Ma question est la suivante scénario spécifique, où mon code ne retourne pas une valeur dans la plage de 0 à 1, et je ne peux pas comprendre comment le code original peut.
- u = 0.5, v = 0.1
- S devient
0.5*0.5 + 0.1*0.1
=0.26
- fac devient ~
3.22
- la valeur de retour est donc ~
0.5 * 3.22
ou ~1.6
Qui n'est pas dans 0 .. 1
.
Ce que je fais mal/ne pas comprendre?
Si j'ai modifier mon code pour que, au lieu de multiplier les fac
avec u
, je multiplie par S
, j'obtiens une valeur qui varie de 0 à 1, mais il a la mauvaise distribution (semble avoir une répartition maximale autour de 0,7-0,8 et puis ralentit dans les deux directions.)
Êtes-vous sûr que le code C génère exactement ce que vous voulez?
OriginalL'auteur Lasse Vågsæther Karlsen | 2011-04-28
Vous devez vous connecter pour publier un commentaire.
Votre code est bien. Votre erreur est de penser qu'il devrait retourner les valeurs exclusivement dans
[0, 1]
. L' (standard) distribution normale est une distribution différente de zéro avec le poids sur l'ensemble de la ligne réelle. Qui est, des valeurs en dehors de[0, 1]
sont possibles. En fait, les valeurs à l'intérieur de[-1, 0]
sont tout aussi susceptibles que les valeurs au sein de[0, 1]
, et de plus, le complément de[0, 1]
a environ 66% du poids de la distribution normale. Par conséquent, 66% du temps, nous nous attendons à une valeur en dehors de[0, 1]
.Aussi, je pense que ce n'est pas le Fort-Mueller transformer, mais est en fait le Marsaglia polaire méthode.
OriginalL'auteur jason
Je ne suis pas mathématicien, ou statisticien, mais si je pense à ce que je ne serait pas s'attendre à une distribution Gaussienne pour retourner les chiffres dans un champ exact. Compte tenu de votre mise en œuvre de la moyenne est 0 et l'écart-type est de 1 donc je m'attends valeurs distribuées sur la courbe en cloche avec 0 au centre et ensuite réduire le nombre s'écarter de 0 sur chaque côté. Donc que la suite serait certainement couvrir à la fois de +/- numéros.
Alors, puisque c'est de la statistique, pourquoi serait-il difficile limité à -1..1 tout simplement parce que le std.dev est de 1? Il peut être statistiquement peu de jeu sur les côtés et encore remplir la statistique exigence.
OriginalL'auteur Chris Taylor
L'uniforme aléatoire de la variable aléatoire est en effet dans 0..1, mais la gaussienne aléatoire de la variable aléatoire (qui est ce de Box-Muller algorithme génère) peut être n'importe où sur la ligne réelle. Voir wiki/NormalDistribution pour plus de détails.
OriginalL'auteur Sasha
Je pense que la fonction retourne les coordonnées polaires. Si vous avez besoin de ces deux valeurs pour obtenir des résultats corrects.
Également, distribution Gaussienne n'est pas entre
0 .. 1
. Il peut facilement se retrouver à 1000, mais la probabilité d'un tel événement est extrêmement faible.OriginalL'auteur Euphoric
C'est une méthode de monte carlo de sorte que vous ne pouvez pas serrer le résultat, mais ce que vous pouvez faire est de l'ignorer échantillons.
OriginalL'auteur Jimmy Jones