С этот вопрос: Генератор случайных чисел, который притягивает числа к любому заданному числу в диапазоне? Я провел некоторое исследование, так как раньше сталкивался с таким генератором случайных чисел.Все, что я помню, было имя «Мюллер», так что, думаю, я нашел его здесь:
Я могу найтимногочисленные реализации этого на других языках, но я не могу реализовать его правильно в C #.
На этой странице, например, Метод Бокса-Мюллера для генерации гауссовских случайных чисел говоритчто код должен выглядеть следующим образом (это не 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;
}
Теперь, вот моя реализация вышеприведенного в C #.Обратите внимание, что преобразование производит 2 числа, отсюда трюк с «фазой» выше.Я просто отбрасываю второе значение и возвращаю первое.
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;
}
Мой вопрос связан со следующим конкретным сценарием, где мой код не возвращает значение в диапазоне 0-1, и я могу 'Я не понимаю, как может исходный код.
- u = 0,5, v = 0,1
- S становится
0.5*0.5 + 0.1*0.1
= 0.26
- fac становится ~
3.22
- поэтому возвращаемое значение равно ~
0.5 * 3.22
или ~ 1.6
Это не в пределах 0 .. 1
.
Что я делаю неправильно /не понимаете?
Если я изменю свой код так, чтобы вместо умножения fac
на u
я умножил на S
, я получил значение в диапазоне от 0 до 1, но оно невернораспределение (кажется, имеет максимальное распределение около 0,7-0,8 и затем сужается в обоих направлениях.)