генератор случайных значений с нормальным распределением для target-c

Я хотел бы сгенерировать числа в массив с нормальным распределением. Есть ли какая-либо функция в target-c или c, которая может помочь легко получить результат без какой-либо математики?


person Infinite Possibilities    schedule 03.03.2013    source источник
comment
Вы правы, но я думал, что есть некоторые методы, которые могут помочь добиться этого намного проще.   -  person Infinite Possibilities    schedule 03.03.2013
comment
Это может помочь: stackoverflow.com/questions/ 12948293/   -  person Khaled Barazi    schedule 03.03.2013


Ответы (2)


Используйте Box-Muller-Transformation:

1.) вам нужны два равномерно распределенных случайных числа u и v как удвоения в интервале (0,1] (0 необходимо исключить):

double u =(double)(random() %100000 + 1)/100000; //for precision
double v =(double)(random() %100000 + 1)/100000; //for precision

2.) рассчитать равномерное распределенное значение со средним значением 0 и сигмой стандартного отклонения, равным 1:

double x = sqrt(-2*log(u))*cos(2*pi*v);   //or sin(2*pi*v)

3.) при необходимости добавьте сигму и среднее значение для вашего целевого распределения следующим образом:

double y = x * sigmaValue + averageValue;

4.) поместите его в массив

[randomNumberArray addObject:[NSNumber numberWithDouble:y]]

Нет функции norminv для objc. Так что здесь нужна математика.

Изменить: мне нравится использовать random(), чтобы иметь возможность запускать генератор случайных значений.

person JFS    schedule 03.03.2013
comment
Это действительно отличное решение, но один вопрос: будет ли это упорядочивать числа? - person Infinite Possibilities; 04.03.2013
comment
К сожалению, этого не будет. И (для больших массивов) рассмотрите возможность проверки и исключения u и v для значений 0 и 1. В противном случае лог-функция не будет работать. - person JFS; 04.03.2013
comment
Что плохого в том, чтобы потом отсортировать его с помощью [randomNumberArray sortedArrayUsingSelector:@selector(compare:)]? - person JFS; 04.03.2013
comment
@JFS, у него должны быть отрицательные числа? - person dwbrito; 18.05.2013
comment
@dwbrito, он также будет генерировать отрицательные числа. Если вы будете следовать уравнениям до шага 2, будут сгенерированы нормально распределенные значения со средним значением, равным нулю (пример: regentsprep.org/Regents/math/algtrig/ATS2/normal67.gif). Таким образом, будут положительные и отрицательные значения. - person JFS; 20.05.2013
comment
@JFS, я думал, что это только минус. В итоге я использовал алгоритм Зиккурата. - person dwbrito; 20.05.2013
comment
@dwbrito, нет, это не просто генерация отрицательных значений. Алгоритм Зиккурата на самом деле похож, но не так прост в реализации, как преобразование Бокса-Мюллера. - person JFS; 20.05.2013

Позвольте мне в предисловии сказать, пожалуйста, поправьте меня, если я ошибаюсь!

Насколько я понимаю, преобразование Бокса-Мюллера основано на том, что исходные числа сами по себе равномерно распределены, поэтому использование random() или rand() в качестве исходного набора данных для Бокса-Мюллера НЕ обязательно производить равномерное распределение.

Вместо этого предполагается взять общий набор равномерно распределенных случайных чисел и создать независимые пары случайных чисел, равномерно распределенных в двумерной системе координат.

Википедия: преобразование Бокса-Мюллера


Однако есть и другой способ:

В большинстве систем Unix (и, следовательно, в Objective C на iOS или OSX) с использованием библиотеки функций rand48:

Ссылка: drand

double drand48(void);
void srand48(long int seedval);

srand48() запускает генератор, а drand48() создает случайные числа, равномерно распределенные в интервале [0,0–1,0].

person Adam    schedule 02.04.2013
comment
спасибо за интересную дискуссию. Пока в интервале (0,1] есть два независимых равномерно распределенных значения, подход Бокса-Мюллера должен генерировать нормально распределенные значения. Но я согласен с тем, что качество источника для генератора случайных чисел влияет на результаты. Я не Мне не нравится качество random(), но мне нужно создать ту же последовательность с нормально распределенными числами. Вот почему я не могу использовать arc4random() или другие лучшие подходы. Как мне реализовать эти функции Unix в iOS? - person JFS; 06.09.2013
comment
Функции srand48() и drand48() доступны в iOS, как сказал @Adam. - person Borzh; 20.11.2015