Экспоненциальное распад-как-случайное распределение и дискретизация непрерывных распределений - PullRequest
0 голосов
/ 05 ноября 2010

к сожалению, я не очень опытен в использовании случайных чисел в программировании, несмотря на использование одинаковых целых чисел в диапазоне.Поэтому у меня есть вопросы по этой теме.

Вопрос 1 (более конкретно):

Я ищу способ выбора элементов массива (динамический размер, ноизвестно) в соответствии с распределением вероятностей, аналогичным кривой «экспоненциальный спад» (http://en.wikipedia.org/wiki/Exponential_decay). Значение: Я хочу предпочесть выбрать первые элементы, а не другиеЯ хочу монотонную убывающую функцию (без увеличения до уменьшения, как во многих известных распределениях вероятностей, таких как гамма-распределение).

Может быть, геометрическое распределение - это то, что я мог бы использовать? Но тогда мне нужноответ на мой второй вопрос, касающийся масштабирования этого распределения по индексам массива.

Двойной метод предпочтения выбора последних элементов, а не первого, конечно, тоже был бы приемлем.

Вопрос 2 (более общий): Существует ли концепция в любой реализации, которая будет масштабировать меня для любого непрерывного случайного распределения to заданный диапазон массива (включая дискретизацию)?

Пример: использовать гауссово нормальное распределение, и результат всегда является допустимым индексом в некотором массиве (что означает: средние элементы предпочтительнее).

Может ли это ( текст ссылки ) быть чем-то вроде того, что я хочу использовать?

Платформа и библиотеки: Я программирую на C ++ и используюбиблиотека boost :: random на данный момент ( текст ссылки ), но я хочу использовать что-то вроде библиотеки gsl или другого Качественные библиотеки.

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

Спасибо!

Ответы [ 5 ]

4 голосов
/ 05 ноября 2010

Общее правило состоит в том, чтобы выбрать свои числа в равномерном распределении, а затем применить функцию, чтобы преобразовать их в желаемое распределение. Применяемая вами функция является обратной к функции, в которую должны попадать случайные числа.

Если вы хотите, чтобы случайные числа выбирались с вероятностью, пропорциональной f (x), тогда вы выбираете случайное число из равномерного распределения u и применяете f ^ -1 (u), и это ваше новое число.

Итак, если вы хотите, чтобы ваши случайные числа выбирались с вероятностью, пропорциональной exp (-x), то вы выбираете равномерно распределенное случайное число и берете его ln:

double x=ln(rand()); 

должно дать вам случайные числа с вероятностным распределением exp (-x).

Примечание: я не говорю, что rand() - хорошая функция для использования, вам нужно изучить детали хороших генераторов случайных чисел. Но, если у вас есть хороший генератор случайных чисел, это хорошее решение.

Редактировать: забыл знак минуса:

double x=-ln(rand()); 

правильный ответ.

2 голосов
/ 05 ноября 2010

Ваш вопрос Q2: «Пример: используйте гауссовское нормальное распределение, и результат всегда является допустимым индексом в некотором массиве (имеется в виду: средние элементы предпочтительны).»

Если я не понимаю, это НЕ правда. Случайная величина, следующая за нормальным распределением, теоретически может принимать значения в диапазоне (-infinity, infinity). Таким образом, если вы не урежете выбросы и не установите значения случайных величин, которые выходят за пределы, скажем, +/- 3 стандартных отклонения, до значения +/- 3-го стандартного отклонения, вы не сможете навязать нормальное распределение конечной сетке.

2 голосов
/ 05 ноября 2010

Q1) То, что вы ищете, это экспоненциальное распределение .Библиотека Boost поставляется с генератором экспоненциального распределения .

Q2) Похоже, вы хотите создать гистограмму .В примере, который вы размещаете на сайте, задайте ячейки средней области вашего массива, чтобы элементы отображались ближе к среднему значению обычных случайных значений, которые вы выводите из распределения.Если у вас недостаточно информации о характере распределения, вам нужно будет собрать репрезентативную выборку из интересующего распределения и сохранить ее в другом массиве.Используя минимальные и максимальные значения выборки, вы можете затем создать еще один массив для подсчета количества элементов выборки в каждой ячейке. Разумное правило заключается в том, что у вас должны быть ячейки sqrt (n), если имеется n выборок.

Обновление: как правильно утверждает Tryer, если вы не сохраняете элементы своего распределения во второй массив до создания своей гистограммы, вам нужно будет найти какой-то способ обработки элементов, которые выходят за пределы установленных вами бинов.

1 голос
/ 06 ноября 2010

Я думаю, что вы не ищете экспоненциальное распределение, так как экспоненциальное распределение предполагает неограниченное количество элементов и, следовательно, дает смещение для последнего элемента вашей последовательности.

Что подходит для вашей проблемы: Бета-дистрибутив с альфа <1 и бета> 1.

1 голос
/ 05 ноября 2010

Я думаю, что разбить эту проблему на два этапа - это хорошее начало. Во-первых, если у вас было дискретное распределение вероятностей, тогда проблема рисования из этого распределения не так уж и плоха. У Boost random есть метод для этого. Прокрутите эту страницу к примеру с взвешенными кубиками. Он вернет целое число из заданного распределения вероятностей. Вы можете использовать это целое число для выбора элемента из интересующего вас массива.

Вторая часть вашего вопроса заключается в том, как перейти от непрерывного распределения вероятностей, например, к экспоненте , к дискретному распределению, подобному тому, которое использовалось в примере повышения. Есть несколько способов, которыми вы могли бы пойти сюда, но, поскольку вы сказали, что вам нужна кривая «как» экспоненциального затухания, я попытаюсь объяснить быстрое и простое понимание того, что мы жертвуем некоторой статистической строгостью.

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

double expDist(int x, double lambda)  
{
   return(lambda*exp(-lambda*x));
}

//code to sample from this distribution
int i,numElements //where numElements has the number of elements in the array you wish to draw from.
vector<double> output;
double sum,temp
sum=0;
for(i=0;i<numElements;i++)
{
   temp=expDist(i,0.5);  //substitute any value you want for lambda in the second argument
   output.push_back(temp); 
   sum+=temp;
}
//after having sampled at all the points we need to divide each element in the array by the variable sum so that the sum of the values in the array is equal to 1 and thus a valid probability distribution
for(i=0;i<numElements;i++)
{
   output[i]/=sum;
}

Затем вы можете передать выходную переменную в пример взвешенных кубиков в библиотеке буста, и он должен соответствовать вашим потребностям. Этот общий метод дискретной выборки, а затем нормализации вектора может работать для многих различных видов распределений.

...