Алгоритм реализован в виде программы на языке С, которую вы можете скачать в разделе программы.
Во всех современных средах программирования существуют функции, генерирующие случайные числа. Чаще всего это бывают случайные числа равномерно распределенные на отрезке [0:1]. Равномерное распределение означает, что сгенерированное случайное число может попасть в любую точку интервала [0:1] с равной вероятностью. (Фраза "в любую точку" не совсем точна, но не будем углубляться в тонкости.)
Однако, для нужд народного хозяйства одного равномерного (uniform, англ.) распределения недостаточно. Во многих задачах в науке встречаются такие случайные явления, вероятность которых зависит от их величины. Например, когда на землю падают космические лучи, энергия каждой частицы - величина случайная, однако частиц с маленькой энергией больше, чем частиц с большой энергией. Аналогично, если мы разбиваем окно, количество осколков - величина случайная, однако маленьких осколков гораздо больше, чем больших.
Пусть f(x) - плотность вероятности случайной величины. Это означает, что чтобы найти вероятность, что случайная величина принимает значение от x до x+dx нужно найти произведение f(x)dx.
Функцией распределения случайной величины называется величина F(x) равная вероятности того, что случайная величина, полученная в некотором событии, меньше x.
Функция распределения и плотность вероятности связаны между собой соотношениями
![]() |
![]() |
В данной статье описано как генерировать случайные числа с определенным распределением вероятности, на примере, когда плотность вероятности обратно пропорциональна некоторой степени величины
![]() |
По определению, вероятность обнаружить случайную величину на всем интервале определения равна единице. Т.е. плотность вероятности должна быть пронормирована:
![]() |
Тогда в случае степенной плотности вероятности
![]() |
![]() |
В таком случае функция распределения будет равна
![]() |
Зная функцию распределения F(x) случайной величины, можно генерировать случайную величину с таким распределением используя генератор равномерно распределенных случайных чисел. Пусть у нас есть генератор, выдающий случайное число r равномерно распределенное на интервале [0:1]. Тогда F -1(r) будет распределено по нужному закону. Здесь F -1(r) означает функцию обратную к F(x).
Обратной функцией к F(x) будет
![]() |
Значит, чтобы найти очередное случайное число, распределенное по нужному закону, зная r, нужно вычислить:
![]() |
Ниже написан пример программы на С, в которой генерируются случайные числа с степенным распределением типа f(x)~x-2. Показатель степени указан в переменной alpha=-2 Сами случайные числа принимают значения от x0=1 до x1=10. Количество случайных чисел управляется переменной N = 300000. Все они пишутся в файл с именем outname = "r.txt". Случайное число, равномерно распределенное на интервале [0:1] обозначено буквой r, сама сгенерированная величина буквой E.
// //generate random numbers with spectra like x^(-2) // #include <stdio.h> #include <stdlib.h> #include <math.h> void main(){ long N = 300000; //number of generated randoms float r=0; //uniform distributed random in [0:1] float alpha=-2; //power of spectra float x0=1; //x min of generated randoms float x1=10; //x max of generated randoms float p0=0, p1=0; //temporary var for powers float E=0; //generated random char* outname = "r.txt"; //name of file of generated randoms FILE* OUT; OUT = fopen(outname, "wt"); p0 = pow(x0, alpha + 1); p1 = pow(x1, alpha + 1); randomize(); for(long i=0; i<N; i++){ r = (float)rand()/RAND_MAX; if(r==0){ //awoid to take log(0) continue; } E = pow(r * (p1 - p0) + p0, 1.0/(alpha + 1.0)); fprintf(OUT, "%f\n", E); } fclose(OUT); }
Надеюсь, что вам стало все понятно.