Реализация генератора случайных чисел бокса-Мюллера в C#
С этот вопрос: генератор случайных чисел, который притягивает числа к любому заданному числу в диапазоне? Я сделал некоторые исследования, так как я сталкивался с таким генератором случайных чисел до. Все, что я помню, было имя "Мюллер", поэтому я думаю, что нашел его здесь:
5 ответов
ваш код в порядке. Ваша ошибка заключается в том, что она должна возвращать значения исключительно в [0, 1]
. (Стандартное) нормальное распределение-это распределение с ненулевым весом по всей реальной линии. То есть значения вне [0, 1]
возможны. Фактически, значения внутри [-1, 0]
так же, как и значения в [0, 1]
, и более того, в дополнение [0, 1]
имеет около 66% от веса нормального распределения. Таким образом, 66% времени мы ожидаем значение за пределами [0, 1]
.
кроме того, я думаю, что это не преобразование бокса-Мюллера, а на самом деле полярный метод Марсалья.
Я не математик или статистик, но если я подумаю об этом, я бы не ожидал, что гауссово распределение вернет числа в точном диапазоне. Учитывая вашу реализацию, среднее значение равно 0, а стандартное отклонение равно 1, поэтому я ожидаю, что значения, распределенные по колоколообразной кривой с 0 в центре, а затем уменьшаются, поскольку числа отклоняются от 0 с обеих сторон. Таким образом, последовательность определенно будет охватывать оба +/- числа.
тогда, поскольку это статистически, почему это было бы трудно общества по -1..1 только потому, что СТД.Дев 1? Статистически может быть некоторая игра с обеих сторон и все еще выполнять статистическое требование.
равномерное случайное изменение действительно находится в пределах 0..1, но Гауссовская случайная вариация (которую генерирует алгоритм бокса-Мюллера) может быть в любом месте на реальной линии. См.wiki / NormalDistribution для сведения.
Я думаю, что функция возвращает полярных координатах. Поэтому вы нужны оба значения, чтобы получить правильные результаты.
кроме того, гауссово распределение не между 0 .. 1
. Он может легко оказаться как 1000, но вероятность такого события крайне низка.
Это метод Монте-Карло, поэтому вы не можете зажать результат, но вы можете игнорировать образцы.
// return random value in the range [0,1].
double gaussian_random()
{
double sigma = 1.0/8.0; // or whatever works.
while ( 1 ) {
double z = gaussian() * sigma + 0.5;
if (z >= 0.0 && z <= 1.0)
return z;
}
}