Опубликован: 19.09.2008 | Доступ: свободный | Студентов: 656 / 70 | Оценка: 4.50 / 5.00 | Длительность: 21:25:00
Лекция 28:

Случайные числа

< Лекция 27 || Лекция 28: 12

27.2. Класс Random

Имея в собственном распоряжении источник поставки случайных чисел, класс Random позволяет программисту извлекать случайные значения разнообразных типов:

class Random a where
   randomR :: RandomGen g => (a, a) -> g -> (a, g)
   random  :: RandomGen g => g -> (a, g)

   randomRs :: RandomGen g => (a, a) -> g -> [a]
   randoms  :: RandomGen g => g -> [a]

   randomRIO :: (a,a) -> IO a
   randomIO :: IO a

- Методы по умолчанию

randoms g = x : randoms g' 
   where 
     (x,g') = random g
   randomRs = ...аналогично...

   randomIO        = getStdRandom random
   randomRIO range = getStdRandom (randomR range)


instance Random Int     where ...
instance Random Integer where ...
instance Random Float   where ...
instance Random Double  where ...
instance Random Bool    where ...
instance Random Char    where ...
  • randomR принимает в качестве аргументов диапазон (lo,hi) и генератор случайных чисел g и возвращает случайное значение, равномерно распределенное в закрытом интервале [lo,hi] вместе с новым генератором. Если lo>hi, то поведение функции в этом случае неопределено. Для непрерывных типов нет требования, чтобы значения lo и hi были когда-либо воспроизведены в качестве случайных значений, но они могут быть использованы в этом качестве, это зависит от реализации и интервала.
  • random выполняет то же самое, что и randomR, но не использует диапазон.
    • Для ограниченных типов (экземпляров класса Bounded, например, Char ), диапазон обычно является целым типом.
    • Для дробных типов диапазон обычно является полузакрытым интервалом [0,1).
    • Для Integer диапазон является (произвольно) диапазон Int.
  • Множественные версии, randomRs и randoms, порождают бесконечный список случайных значений и не возвращают новый генератор.
  • Версии IO, randomRIO и randomIO, используют глобальный генератор случайных чисел (см. раздел "Случайные числа" ).

27.3. Глобальный генератор случайных чисел

Есть единственный, неявный, глобальный генератор случайных чисел типа StdGen, который хранится в некоторой глобальной переменной, поддерживаемой монадой IO. Он инициализируется автоматически некоторым зависящим от системы способом, например, посредством использования времени дня или генератора случайных чисел в ядре Linux. Для того чтобы получить детерминированное поведение, используйте setStdGen.

setStdGen    :: StdGen -> IO () 
  getStdGen    :: IO StdGen 
  newStdGen    :: IO StdGen
  getStdRandom :: (StdGen -> (a, StdGen)) -> IO a
  • getStdGen и setStdGen соответственно возвращают и устанавливают глобальный генератор случайных чисел.
  • newStdGen применяет split по отношению к текущему глобальному генератору случайных чисел, обновляет его одним из результатов и возвращает другой.
  • getStdRandom использует указанную функцию, чтобы получить значение из текущего глобального генератора случайных чисел, и обновляет глобальный генератор с помощью нового генератора, возвращенного функцией. Например, rollDice возвращает случайное целое число между 1 и 6:
    rollDice :: IO Int
      rollDice = getStdRandom (randomR (1,6))

Ссылки

[1] FW Burton and RL Page, "Distributed random number generation", Journal of Functional Programming, 2(2):203-212, April 1992.

Ф.У. Бертон и Р.Л. Пейдж, "Генерация распределенных случайных чисел", Журнал "Функциональное программирование", 2 (2):203-212, апрель 1992.

[2] SK Park, and KW Miller, "Random number generators - good ones are hard to find", Comm ACM 31(10), Oct 1988, pp1192-1201.

С.К. Парк и К.У. Миллер, "Генераторы случайных чисел - трудно найти хорошие", Comm ACM 31 (10), октябрь 1988, стр.1192-1201.

[3] DG Carta, "Two fast implementations of the minimal standard random number generator", Comm ACM, 33(1), Jan 1990, pp87-88.

Д.Г. Карта, "Две быстрые реализации минимального стандартного генератора случайных чисел", Comm ACM, 33 (1), январь 1990, стр.87-88.

[4] P Hellekalek, "Don't trust parallel Monte Carlo", ACM SIGSIM Simulation Digest 28(1), pp82-89, July 1998.

П. Хеллекалек, "Не доверяйте параллельному методу Монте-Карло ", ACM SIGSIM Simulation Digest 28 (1), стр.82-89, июль 1998.

Web-cайт http://random.mat.sbg.ac.at/ является большим источником информации.

< Лекция 27 || Лекция 28: 12
Николай Щербаков
Николай Щербаков
Россия, Москва
Олег Корсак
Олег Корсак
Латвия, Рига