| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- (* ************************************
- Генератор какбыслучайных чисел,
- Линейный конгруэнтный метод,
- алгоритм Лемера.
- Вадим Исаев, 2020
- -------------------------------
- Generator pseudorandom numbers,
- Linear congruential generator,
- Algorithm by D. H. Lehmer.
- Vadim Isaev, 2020
- *************************************** *)
- MODULE Rand;
- IMPORT HOST, Math;
- CONST
- RAND_MAX = 2147483647;
- VAR
- seed: INTEGER;
- PROCEDURE Randomize*;
- BEGIN
- seed := HOST.GetTickCount()
- END Randomize;
- (* Целые какбыслучайные числа 0..RAND_MAX-1 *)
- PROCEDURE RandomI* (): INTEGER;
- CONST
- a = 630360016;
- BEGIN
- seed := (a * seed) MOD RAND_MAX
- RETURN seed
- END RandomI;
- (* Какбыслучайные числа с плавающей запятой [0, 1) *)
- PROCEDURE RandomR* (): REAL;
- RETURN FLT(RandomI()) / FLT(RAND_MAX)
- END RandomR;
- (* Какбыслучайное число в диапазоне 0..aTo-1
- Return a random number in a range 0..aTo-1 *)
- PROCEDURE RandomITo* (aTo: INTEGER): INTEGER;
- RETURN FLOOR(RandomR() * FLT(aTo))
- END RandomITo;
- (* Какбыслучайное число в диапазоне.
- Return a random number in a range *)
- PROCEDURE RandomIRange* (aFrom, aTo: INTEGER): INTEGER;
- RETURN FLOOR(RandomR() * FLT(aTo - aFrom + 1)) + aFrom
- END RandomIRange;
- (* Какбыслучайное число. Распределение Гаусса *)
- PROCEDURE RandG* (mean, stddev: REAL): REAL;
- VAR
- U, S: REAL;
- BEGIN
- REPEAT
- U := 2.0 * RandomR() - 1.0;
- S := Math.sqrr(U) + Math.sqrr(2.0 * RandomR() - 1.0)
- UNTIL (1.0E-20 < S) & (S <= 1.0)
- RETURN Math.sqrt(-2.0 * Math.ln(S) / S) * U * stddev + mean
- END RandG;
- BEGIN
- seed := 654321
- END Rand.
|