Случайное число в диапазоне на основе нормального распределения

Я хочу генерировать случайные числа с диапазоном (n к m, например, 100 - 150), но вместо чисто случайного я хочу, чтобы результаты были основаны на нормальном распределении.

Этим я подразумеваю, что в целом хочу числа, "кластеризируемые" приблизительно 125.

Я нашел этот пакет случайного числа, который, кажется, имеет многое из того, в чем я нуждаюсь: http://codeproject.com/KB/recipes/Random.aspx

Это поддерживает множество случайных генераторов (включайте mersiene обманщика), и может применить генератор к распределению.

Но я смущен, если я использую генератор нормального распределения, случайные числа примерно от-6 до +8 (по-видимому, истинный диапазон является float.min к float.max).

Как делают масштаб это к моему необходимому диапазону?

34
задан Peter O. 19 March 2016 в 11:15
поделиться

4 ответа

Стандартное нормальное распределение имеет среднее 0 и стандартное отклонение 1; если вы хотите получить распределение со средним m и отклонением s, просто умножьте на s, а затем добавьте m. Поскольку нормальное распределение теоретически бесконечно, вы не можете установить жесткий предел диапазона, например (от 100 до 150), не отвергая явно числа, выходящие за его пределы, но при соответствующем выборе отклонения вы можете быть уверены, что (например) 99% ваших чисел будут находиться в пределах диапазона.

Около 99,7% популяции находится в пределах +/- 3 стандартных отклонений, поэтому если вы выберете отклонение около (25/3), это должно сработать хорошо.

Итак, вам нужно что-то вроде: (normal * 8.333) + 125

26
ответ дан 27 November 2019 в 17:03
поделиться

Ответ tzaman правильный, но при использовании библиотеки, которую вы связали, есть более простой способ, чем выполнять вычисления самостоятельно: Объект NormalDistribution имеет записываемые свойства Mu (означает среднее значение) и Sigma (стандартное отклонение). Итак, следуя числам tzaman, установите Mu равным 125 и Sigma равным 8.333.

4
ответ дан 27 November 2019 в 17:03
поделиться

Ради интереса, довольно просто генерировать нормально распределенные случайные числа из равномерного ГПСЧ (хотя это нужно делать попарно):

Random rng = new Random();
double r = Math.Sqrt(-2 * Math.Log(rng.NextDouble()));
double θ = 2 * Math.Pi * rng.NextDouble();
double x = r * Math.Cos(θ);
double y = r * Math.Sin(θ);

x и y теперь содержат два независимых, нормально распределенных случайных числа со средним 0 и дисперсией 1. Вы можете масштабировать и переводить их по мере необходимости, чтобы получить нужный вам диапазон (как объясняет interjay).


Пояснение:

Этот метод называется преобразованием Бокса-Маллера. Он использует свойство двумерного единичного гаусса, что само значение плотности, p = exp(-r^2/2), равномерно распределено между 0 и 1 (константа нормировки для простоты удалена).

Поскольку такое значение можно легко сгенерировать с помощью равномерного ГПСЧ, в итоге получается круговой контур радиуса r = sqrt(-2 * log(p)). Затем вы можете сгенерировать вторую равномерную случайную величину между 0 и 2*pi, чтобы получить угол θ, который определяет уникальную точку на вашем круговом контуре. Наконец, вы можете сгенерировать две i.i.d. нормальные случайные величины, преобразовав полярные координаты (r, θ) обратно в картезианские координаты (x, y).

Это свойство - то, что p равномерно распределено - не выполняется для других размерностей, вот почему вы должны генерировать ровно две нормальные переменные за раз.

14
ответ дан 27 November 2019 в 17:03
поделиться

Это может быть слишком упрощенно для ваших нужд, но быстрый и дешевый способ получить случайное число с распределением, взвешенным к центру, - это просто добавить 2 (или более) случайных числа.

Подумайте, когда вы бросаете два шестигранных кубика и складываете их. Чаще всего получается 7, затем 6 и 8, затем 5 и 9 и т. Д. И лишь изредка 2 или 12.

2
ответ дан 27 November 2019 в 17:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: