Rand.ob07 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. (* ************************************
  2. Генератор какбыслучайных чисел,
  3. Линейный конгруэнтный метод,
  4. алгоритм Лемера.
  5. Вадим Исаев, 2020
  6. -------------------------------
  7. Generator pseudorandom numbers,
  8. Linear congruential generator,
  9. Algorithm by D. H. Lehmer.
  10. Vadim Isaev, 2020
  11. *************************************** *)
  12. MODULE Rand;
  13. IMPORT HOST, Math;
  14. CONST
  15. RAND_MAX = 2147483647;
  16. VAR
  17. seed: INTEGER;
  18. PROCEDURE Randomize*;
  19. BEGIN
  20. seed := HOST.GetTickCount()
  21. END Randomize;
  22. (* Целые какбыслучайные числа 0..RAND_MAX-1 *)
  23. PROCEDURE RandomI* (): INTEGER;
  24. CONST
  25. a = 630360016;
  26. BEGIN
  27. seed := (a * seed) MOD RAND_MAX
  28. RETURN seed
  29. END RandomI;
  30. (* Какбыслучайные числа с плавающей запятой [0, 1) *)
  31. PROCEDURE RandomR* (): REAL;
  32. RETURN FLT(RandomI()) / FLT(RAND_MAX)
  33. END RandomR;
  34. (* Какбыслучайное число в диапазоне 0..aTo-1
  35. Return a random number in a range 0..aTo-1 *)
  36. PROCEDURE RandomITo* (aTo: INTEGER): INTEGER;
  37. RETURN FLOOR(RandomR() * FLT(aTo))
  38. END RandomITo;
  39. (* Какбыслучайное число в диапазоне.
  40. Return a random number in a range *)
  41. PROCEDURE RandomIRange* (aFrom, aTo: INTEGER): INTEGER;
  42. RETURN FLOOR(RandomR() * FLT(aTo - aFrom + 1)) + aFrom
  43. END RandomIRange;
  44. (* Какбыслучайное число. Распределение Гаусса *)
  45. PROCEDURE RandG* (mean, stddev: REAL): REAL;
  46. VAR
  47. U, S: REAL;
  48. BEGIN
  49. REPEAT
  50. U := 2.0 * RandomR() - 1.0;
  51. S := Math.sqrr(U) + Math.sqrr(2.0 * RandomR() - 1.0)
  52. UNTIL (1.0E-20 < S) & (S <= 1.0)
  53. RETURN Math.sqrt(-2.0 * Math.ln(S) / S) * U * stddev + mean
  54. END RandG;
  55. BEGIN
  56. seed := 654321
  57. END Rand.