Генератор псевдослучайных чисел – экспоненциальное распределение

Я хотел бы генерировать некоторые псевдослучайные числа, и до сих пор я был очень доволен Random.Next(int min, int max) .Net библиотеки Random.Next(int min, int max) . Предполагается, что PRNG этого сорта используют Uniform-распределение , но я очень хотел бы генерировать некоторые числа, используя Exponential Distribution .

Я программирую на C #, хотя я буду принимать псевдокод или C ++, Java или тому подобное.

Любые предложения / fragmentы кода / алгоритмы / мысли?

    7 Solutions collect form web for “Генератор псевдослучайных чисел – экспоненциальное распределение”

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

    Итак, сгенерируем равномерное случайное число u в [0,1) , а затем вычислим x образом:

    x = log(1-u)/() ,

    где λ – параметр скорости экспоненциального распределения. Теперь x – случайное число с экспоненциальным распределением. Обратите внимание, что log выше ln , натуральный логарифм.

    Основная теорема выборки считает, что если вы можете нормализовать, интегрировать и инвертировать желаемый дистрибутив, вы свободны на дому.

    Если у вас есть искомое распределение F(x) нормированное на [a,b] . Вы вычисляете

     C(y) = \int_a^y F(x) dx 

    инвертируйте, чтобы получить C^{-1} , равномерно распределить z на [0,1) и найти

     x_i = C^{-1}(z_i) 

    который будет иметь желаемое распределение.


    В вашем случае: F(x) = ke^{-kx} и я предполагаю, что вы хотите [0,infinity] . Мы получаем :

     C(y) = 1 - e^{-ky} 

    который является обратимым, чтобы дать

     x = -1/k ln(1 - z) 

    для z выбрасывается равномерно на [0,1) .


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

    Если вы хотите получить хорошие случайные числа, подумайте о ссылке на подпрограммы gsl: http://www.gnu.org/software/gsl/ . У них есть обычная gsl_ran_exponential . Если вы хотите генерировать случайные числа, используя встроенный генератор с равномерным распределением на [0, 1) (например, u = Random.Next (0, N-1) / N, для некоторого большого N), просто используйте:

     -mu * log (1-u) 

    См. Randist / exponential.c в источнике gsl.

    EDIT: просто для сравнения с некоторыми более поздними ответами – это эквивалентно mu = 1 / lambda. mu здесь – среднее значение распределения, также называемое параметром scale на странице wikipedia, связанной с OP, и lambda – параметр скорости.

    Одно интересное свойство экспоненциального распределения: рассмотрим процесс прибытия с экспоненциальными промежутками времени. Возьмите любой период времени (t1, t2) и прибытия в этот период. Эти поступления UNIFORMLY распределены между t1 и t2. (Шелдон Росс, Стохастические процессы).

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

    Ты можешь :

    1) Создать 1001 U (0,1) случайных величин.

    2) Сортировать по порядку

    3) Вычтите второй из первого, третьего со второго, … чтобы получить 1000 различий.

    4) Эти различия представляют собой экспоненциальные RV с распределением со средним значением = 1,0.

    Менее эффективно, я думаю, но средство для достижения той же цели.

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

    Среди других ценных classов ExponentialGenerator существенно реализовал идею, объясненную @Alok Singhal. В своем учебном блоге приведен fragment кода для моделирования случайного события, которое произошло в среднем 10 раз в минуту:

     final long oneMinute = 60000; Random rng = new MersenneTwisterRNG(); // Generate events at an average rate of 10 per minute. ExponentialGenerator gen = new ExponentialGenerator(10, rng); boolean running = true; while (true) { long interval = Math.round(gen.nextValue() * oneMinute); Thread.sleep(interval); // Fire event here. } 

    Конечно, если вы предпочитаете единицу времени per second (вместо a minute здесь), вам просто нужно установить final long oneMinute = 1000 .

    Подойдя глубже в исходный код метода nextValue() ExponentialGenerator , вы найдете так называемую выборку обратного преобразования, описанную в Generation_exponential_variates [wiki] :

     public Double nextValue() { double u; do { // Get a uniformly-distributed random double between // zero (inclusive) and 1 (exclusive) u = rng.nextDouble(); } while (u == 0d); // Reject zero, u must be positive for this to work. return (-Math.log(u)) / rate.nextValue(); } 

    PS: Недавно я использую библиотеку Uncommons Maths. Спасибо Дэн Дайер.

    Если я понимаю вашу проблему, и вы можете принять конечное число PRNG, вы можете следовать подходу вроде:

    • Создайте массив, в котором каждый элемент находится в вашем экспоненциальном распределении
    • Создайте PRNG, который является целым индексом в массиве. Верните элемент в массив по этому индексу.

    Это то, что я использовал, когда сталкивался с аналогичными требованиями:

     // sorry.. pseudocode, mine was in Tcl: int weighted_random (int max) { float random_number = rand(); return floor(max - ceil( max * random_number * random_number)) } 

    Конечно, это формула квадратизации случайного числа, поэтому вы производите случайное число по квадратичной кривой.

    Interesting Posts

    Как контролировать папку и запускать действие командной строки при создании или редактировании файла?

    Что заставляет Android ContentResolver.query () вернуть null?

    Хостинг внешнего приложения в окне WPF

    count vs length vs size в коллекции

    В чем разница между синхронизированным методом и синхронизированным блоком в Java?

    Текст центра Java в прямоугольнике

    Как вставить время и дату, а также путь к каталогу в Notepad ++?

    Каков наилучший способ загрузить JSONObject из текстового файла json?

    ASP.NET MVC – Медленная начальная загрузка

    Использование Powercfg для удаления файла гибернации не работает, хотя я являюсь администратором

    Вставить, если не существует, иначе вернуть id в postgresql

    Комбинация смешанного режима построена против версии «v2.0.50727» среды выполнения

    Требуется ли антивирусное программное обеспечение для Mac (OS X); Если это бесплатное решение?

    Включить подсказку углового ui для пользовательских событий

    Android – ListView – performItemClick

    Давайте будем гением компьютера.