Sign in Join
Wiki copytemporary

Generating Random Numbers/ru: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: Generating Random Numbers/ru

OldNewLine
1+<figure>
2+<img src="fpc_source_logo.png" title="fpc_source_logo.png" />
3+<figcaption>fpc_source_logo.png</figcaption>
4+</figure>
5+
6+**Случайные числа** являются важными ресурсами для научных приложений, образования, разработки игр и визуализации. Они играют ключевую роль в численном моделировании.
7+
8+Генерируемые алгоритмом случайные числа являются псевдослучайными числами. Они принадлежат (большому) набору повторяющихся чисел, последовательность которых невозможно или, по крайней мере, трудно предсказать. В отличие от Delphi, в котором используется линейный конгруэнтный генератор (см. [[Delphi compatible LCG Random]]), Free Pascal использует алгоритм MersenneTwister для своей стандартной [[doc:rtl/system/random.html|random]] функции, определенной в [[RTL]]. Перед первым использованием генератор случайных чисел FPC должен быть проинициализирован единичным вызовом функции [[doc:rtl/system/randomize.html|randomize]], которая устанавливает начальное число генератора. Предпочтительнее это делать на этапе запуска программы.
9+
10+Кроме того, в системах на основе Unix и Linux доступны виртуальные устройства [[Dev random|/dev/random]] и `/dev/urandom`. Они генерируют (псевдо) случайные числа на основе оборудования.
11+
12+Третий вариант - использовать случайные числа из внешних источников, либо из специализированных аппаратных устройств, либо из общедоступных источников, например. на основе данных радиоактивного распада.
13+
14+## Равномерное распределение
15+
16+Непрерывное равномерное распределение (также называемое прямоугольным распределением) представляет собой семейство симметричных вероятностных распределений. Здесь для каждого члена семьи все интервалы одинаковой длины в поддержке распределения одинаково вероятны.
17+
18+Стандартная функция [[RTL]] [[doc:rtl/system/random.html|random]] генерирует случайные числа с равномерным распределением. При вызове без параметра `random` выдает псевдослучайное число с плавающей запятой в интервале \[0, 1), т.е. 0 \<= result \< 1. Если `random` вызывается с аргументом `longint L`, возвращается случайное значение longint в интервале \[0, L).
19+
20+Дополнительный набор равномерно распределенных генераторов случайных чисел представлен в [[Marsaglia&|генераторах псевдослучайных чисел Марсальи.]]\
21+\
22+Равномерно распределенные случайные числа полезны не для каждого приложения. Для создания случайных чисел других распределений необходимы специальные алгоритмы.
23+
24+## Нормальное (гауссово) распределение
25+
26+Одним из наиболее распространенных алгоритмов получения нормально распределенных случайных чисел из равномерно распределенных случайных чисел является [преобразование Бокса-Мюллера](https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B5%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%91%D0%BE%D0%BA%D1%81%D0%B0_%E2%80%94_%D0%9C%D1%8E%D0%BB%D0%BB%D0%B5%D1%80%D0%B0). Следующая функция вычисляет распределенные по Гауссу случайные числа:
27+
28+``` pascal
29+ function rnorm (mean, sd: real): real;
30+ {Вычисляет гауссовы случайные числа в соответствии с преобразованием Бокса-Мюллера}
31+ var
32+ u1, u2: real;
33+ begin
34+ u1 := random;
35+ u2 := random;
36+ rnorm := mean * abs(1 + sqrt(-2 * (ln(u1))) * cos(2 * pi * u2) * sd);
37+ end;
38+```
39+
40+Тот же алгоритм используется функцией randg [[doc:rtl/math/randg.html|randg]] из модуля [[RTL]] [[doc:rtl/math/index.html|math]]:
41+
42+``` pascal
43+function randg(mean,stddev: float): float;
44+```
45+
46+## Экспоненциальное распределение
47+
48+Экспоненциальное распределение часто встречается в реальных задачах. Классическим примером является распределение времени ожидания между независимыми пуассоновскими случайными событиями, например, радиоактивный распад ядер \[Press et al. 1989\].
49+
50+Следующая функция возвращает одно действительное случайное число из экспоненциального распределения. *Rate* является обратным к среднему значению, а константа *RESOLUTION* определяет гранулярность генерируемых случайных чисел.
51+
52+``` pascal
53+function randomExp(a, rate: real): real;
54+const
55+ RESOLUTION = 1000;
56+var
57+ unif: real;
58+begin
59+ if rate = 0 then
60+ randomExp := NaN
61+ else
62+ begin
63+ repeat
64+ unif := random(RESOLUTION) / RESOLUTION;
65+ until unif <> 0;
66+ randomExp := a - rate * ln(unif);
67+ end;
68+end;
69+```
70+
71+## Гамма-распределение
72+
73+Гамма-распределение - это двухпараметрическое семейство непрерывных случайных распределений. Это обобщение как экспоненциального распределения, так и распределения Эрланга. Возможные применения гамма-распределения включают моделирование и имитацию линий ожидания, или очередей, и актуарную(страховую) науку.
74+
75+Следующая функция возвращает одно действительное случайное число из гамма-распределения. Форма распределения определяется параметрами *a*, *b* и *c*. Функция использует функцию **randomExp**, как определено выше.
76+
77+``` pascal
78+function randomGamma(a, b, c: real): real;
79+const
80+ RESOLUTION = 1000;
81+ T = 4.5;
82+ D = 1 + ln(T);
83+var
84+ unif: real;
85+ A2, B2, C2, Q, p, y: real;
86+ p1, p2, v, w, z: real;
87+ found: boolean;
88+begin
89+ A2 := 1 / sqrt(2 * c - 1);
90+ B2 := c - ln(4);
91+ Q := c + 1 / A2;
92+ C2 := 1 + c / exp(1);
93+ found := False;
94+ if c < 1 then
95+ begin
96+ repeat
97+ repeat
98+ unif := random(RESOLUTION) / RESOLUTION;
99+ until unif > 0;
100+ p := C2 * unif;
101+ if p > 1 then
102+ begin
103+ repeat
104+ unif := random(RESOLUTION) / RESOLUTION;
105+ until unif > 0;
106+ y := -ln((C2 - p) / c);
107+ if unif <= power(y, c - 1) then
108+ begin
109+ randomGamma := a + b * y;
110+ found := True;
111+ end;
112+ end
113+ else
114+ begin
115+ y := power(p, 1 / c);
116+ if unif <= exp(-y) then
117+ begin
118+ randomGamma := a + b * y;
119+ found := True;
120+ end;
121+ end;
122+ until found;
123+ end
124+ else if c = 1 then
125+ { Гамма-распределение становится экспоненциальным, если c = 1 }
126+ begin
127+ randomGamma := randomExp(a, b);
128+ end
129+ else
130+ begin
131+ repeat
132+ repeat
133+ p1 := random(RESOLUTION) / RESOLUTION;
134+ until p1 > 0;
135+ repeat
136+ p2 := random(RESOLUTION) / RESOLUTION;
137+ until p2 > 0;
138+ v := A2 * ln(p1 / (1 - p1));
139+ y := c * exp(v);
140+ z := p1 * p1 * p2;
141+ w := B2 + Q * v - y;
142+ if (w + D - T * z >= 0) or (w >= ln(z)) then
143+ begin
144+ randomGamma := a + b * y;
145+ found := True;
146+ end;
147+ until found;
148+ end;
149+end;
150+```
151+
152+## Распределение Эрланга
153+
154+Распределение Эрланга - это двухпараметрическое семейство непрерывных распределений вероятностей. Это обобщение экспоненциального распределения и частный случай гамма-распределения, где *c* - целое число. Распределение Эрланга было впервые описано Агнером Крарупом Эрлангом для моделирования временного интервала между телефонными звонками. Он используется для теории очередей и для моделирования линий ожидания.
155+
156+``` pascal
157+ function randomErlang(mean: real; k: integer): real;
158+ const
159+ RESOLUTION = 1000;
160+ var
161+ i: integer;
162+ unif, prod: real;
163+ begin
164+ if (mean <= 0) or (k < 1) then
165+ randomErlang := NaN
166+ else
167+ begin
168+ prod := 1;
169+ for i := 1 to k do
170+ begin
171+ repeat
172+ unif := random(RESOLUTION) / RESOLUTION;
173+ until unif <> 0;
174+ prod := prod * unif;
175+ end;
176+ randomErlang := -mean * ln(prod);
177+ end;
178+ end;
179+```
180+
181+## Распределение Пуассона
182+
183+Распределение Пуассона применяется к целочисленным значениям. Оно представляет вероятность успеха *k*, когда вероятность успеха в каждом испытании мала, а частота появления (среднее значение) постоянна.
184+
185+``` pascal
186+function randomPoisson(mean: integer): integer;
187+{ Генератор для распределения Пуассона (алгоритм Дональда Кнута) }
188+const
189+ RESOLUTION = 1000;
190+var
191+ k: integer;
192+ b, l: real;
193+begin
194+ assert(mean > 0, 'mean < 1');
195+ k := 0;
196+ b := 1;
197+ l := exp(-mean);
198+ while b > l do
199+ begin
200+ k := k + 1;
201+ b := b * random(RESOLUTION) / RESOLUTION;
202+ end;
203+ randomPoisson := k - 1;
204+end;
205+```
206+
207+## t-распределение (Стьюдента)
208+
209+t-распределение (также относится к t-распределению Стьюдента, поскольку оно было опубликовано Уильямом Сили Госсетом в 1908 году под псевдонимом *Student*) - это непрерывное распределение вероятностей. Его форма определяется одним параметром, степенями свободы (*df*). В статистике много оценок являются t-распределением. Таким образом, t-распределение Стьюдента играет главную роль в ряде широко используемых статистических анализов, включая t-критерий Стьюдента для оценки статистической значимости разницы между двумя средними выборками, построение доверительных интервалов для разницы между двумя средними значениями, и в линейном регрессионном анализе. Т-распределение также возникает при Байесовском выводе данных из нормального семейства.
210+
211+Следующий алгоритм зависит от функции [[RTL]] [[doc:rtl/system/random.html|random]] и от функции **randomChisq**
212+
213+``` pascal
214+function randomT(df: integer): real;
215+{ Генератор для распределения Стьюдента }
216+begin
217+ if df < 1 then
218+ randomT := NaN
219+ else begin
220+ randomT := randg(0, 1) / sqrt(randomChisq(df) / df);
221+ end;
222+end;
223+```
224+
225+## Распределение хи-квадрат
226+
227+Распределение хи-квадрат - это непрерывное распределение случайных чисел со степенями свободы *df*. Это распределение суммы квадратов независимых стандартных нормальных случайных величин. Распределение хи-квадрат имеет множество применений в выводной статистике, например, в оценке дисперсий и для тестов хи-квадрат. Это специальное гамма-распределение с *c* = *df*/ 2 and *b* = 2. Поэтому следующая функция зависит от функции **randomGamma**.
228+
229+``` pascal
230+function randomChisq(df: integer): real;
231+begin
232+ if df < 1 then
233+ randomChisq := NaN
234+ else
235+ randomChisq := randomGamma(0, 2, 0.5 * df);
236+end;
237+```
238+
239+## F-распределение (Фишера)
240+
241+Распределение F, также называемое распределением Фишера-Снедекора, является непрерывным распределением вероятности. Используется для F-теста(критерия Фишера) и ANOVA(ANalysis Of VAriance, или дисперсионный анализ). Оно имеет две степени свободы, которые служат параметрами формы *v* и *w*, и являются положительными целыми числами. Следующая функция **randomF** использует **randomChisq**.
242+
243+``` pascal
244+function randomF(v, w: integer): real;
245+begin
246+ if (v < 1) or (w < 1) then
247+ randomF := NaN
248+ else
249+ randomF := randomChisq(v) / v / (randomChisq(w) / w);
250+end;
251+```
252+
253+## См.также
254+
255+- [[Dev random]]
256+- [[Functions for descriptive statistics]]
257+- [[Marsaglia&|Marsaglia's pseudo random number generators]]
258+- [[A simple implementation of the Mersenne twister]]
259+- [[Delphi compatible LCG Random]]
260+
261+## Рекомендации
262+
263+1. [G. E. P. Box and Mervin E. Muller, *A Note on the Generation of Random Normal Deviates*, The Annals of Mathematical Statistics (1958), Vol. 29, No. 2 pp. 610–611](http://projecteuclid.org/DPubS/Repository/1.0/Disseminate?view=body&id=pdf_1&handle=euclid.aoms/1177706645)
264+2. Dietrich, J. W. (2002). [Der Hypophysen-Schilddrüsen-Regelkreis](http://openlibrary.org/books/OL24586469M/Der_Hypophysen-Schilddrüsen-Regelkreis). Berlin, Germany: Logos-Verlag Berlin. ISBN 978-3-89722-850-4. OCLC 50451543.
265+3. Press, W. H., B. P. Flannery, S. A. Teukolsky, W. T. Vetterling (1989). [Numerical Recipes in Pascal](http://openlibrary.org/works/OL16807779W/). The Art of Scientific Computing, Cambridge University Press, ISBN 0-521-37516-9.
266+4. Richard Saucier, [Computer Generation of Statistical Distributions](http://ftp.arl.mil/random/random.pdf), ARL-TR-2168, US Army Research Laboratory, Aberdeen Proving Ground, MD, 21005-5068, March 2000.
267+5. R.U. Seydel, Generating Random Numbers with Specified Distributions. In: Tools for Computational Finance, Universitext, [DOI 10.1007/978-1-4471-2993-6_2](http://dx.doi.org/10.1007/978-1-4471-2993-6_2), © Springer-Verlag London Limited 2012
268+6. Christian Walck, Hand-book on STATISTICAL DISTRIBUTIONS for experimentalists, Internal Report SUF–PFY/96–01, University of Stockholm 2007
269+
270+\
271+
272+---
273+*From the Free Pascal wiki, page "Generating Random Numbers/ru", as it stood on 2019-07-26 after a change by Zoltanleo, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history