Spec-Zone.ru › Nim 1

random

Стандартный генератор случайных чисел Nim.

Его реализация основана на библиотеке xoroshiro128+ (xor/rotate/shift/rotate).

  • Дополнительная информация: http://xoroshiro.di.unimi.it/
  • Реализация на C: http://xoroshiro.di.unimi.it/xoroshiro128plus.c

Не используйте этот модуль для криптографических целей!

Основные примеры использования

Для начала, вот несколько примеров:

import random

# Call randomize() once to initialize the default random number generator
# If this is not called, the same results will occur every time these
# examples are run
randomize()

# Pick a number between 0 and 100
let num = rand(100)
echo num

# Roll a six-sided die
let roll = rand(1..6)
echo roll

# Pick a marble from a bag
let marbles = ["red", "blue", "green", "yellow", "purple"]
let pick = sample(marbles)
echo pick

# Shuffle some cards
var cards = ["Ace", "King", "Queen", "Jack", "Ten"]
shuffle(cards)
echo cards

Все эти примеры используют генератор случайных чисел по умолчанию. Тип Rand представляет состояние генератора случайных чисел. Для удобства этот модуль содержит состояние Rand по умолчанию, которое соответствует состоянию генератора случайных чисел по умолчанию. Большинство процедур в этом модуле, которые не принимают параметр Rand, включая те, которые вызываются в вышеприведенных примерах, используют генератор по умолчанию. Эти процедуры не потокобезопасны.

Обратите внимание, что генератор по умолчанию всегда начинает с одного и того же состояния. Процедура randomize может быть вызвана для инициализации генератора по умолчанию с помощью начального значения, основанного на текущем времени, и её необходимо вызвать только один раз перед первым использованием процедур из этого модуля. Если randomize не вызывается, то генератор по умолчанию всегда будет давать одни и те же результаты.

Генераторы, независимые от генератора по умолчанию, могут быть созданы с помощью процедуры initRand.

Опять же, важно помнить, что этот модуль не должен использоваться в криптографических приложениях.

См. также

  • Модуль math для основных математических процедур
  • Модуль mersenne для генератора случайных чисел Mersenne Twister
  • Модуль stats для статистического анализа
  • Список криптографических и хеширующих модулей в стандартной библиотеке

Импорты

algorithm, math, since, times

Типы

Rand = object
  a0, a1: Ui

Состояние генератора случайных чисел.

Создайте новое состояние Rand, используя процедуру initRand.

Модуль содержит состояние Rand по умолчанию для удобства. Оно соответствует состоянию генератора случайных чисел по умолчанию. Состояние Rand по умолчанию всегда начинается с одних и тех же значений, но процедура randomize может быть использована для инициализации генератора по умолчанию значением, основанным на текущем времени.

Многие процедуры имеют две разновидности: одна принимает параметр Rand, а другая использует генератор по умолчанию. Процедуры, использующие генератор по умолчанию, не потокобезопасны!

Исходный код Редактировать

Процедуры

proc next(r: var Rand): uint64 {...}{.raises: [], tags: [].}

Вычисляет случайное uint64 число, используя заданное состояние.

См. также:

  • процедуру rand которая возвращает целое число от нуля до заданного верхнего предела
  • процедуру rand которая возвращает число с плавающей запятой
  • процедуру rand которая принимает срез
  • процедуру rand которая принимает целочисленный или диапазонный тип
  • процедуру skipRandomNumbers

Пример:

var r = initRand(2019)
doAssert r.next() == 138_744_656_611_299'u64
doAssert r.next() == 979_810_537_855_049_344'u64
doAssert r.next() == 3_628_232_584_225_300_704'u64
Исходный код Редактировать
proc skipRandomNumbers(s: var Rand) {...}{.raises: [], tags: [].}

Функция перехода для генератора.

Эта процедура эквивалентна 2^64 вызовам next и может быть использована для генерации 2^64 непересекающихся подпоследовательностей для параллельных вычислений.

Когда несколько потоков генерируют случайные числа, каждый поток должен владеть состоянием Rand, которое он использует, чтобы поток мог безопасно получить случайные числа. Однако, если каждый поток создаёт своё собственное состояние Rand, подпоследовательности случайных чисел, генерируемые каждым потоком, могут перекрываться, даже если предоставленные семена уникальны. Это с большей вероятностью произойдёт по мере увеличения количества потоков и объёма генерируемых случайных чисел.

Если многие потоки будут генерировать случайные числа одновременно, лучше создать одно состояние Rand и передать его каждому потоку. После передачи состояния Rand потоку вызовите эту процедуру перед передачей его следующему. Используя состояние Rand таким образом, подпоследовательности случайных чисел, генерируемые в каждом потоке, никогда не будут перекрываться, пока ни один поток не сгенерирует больше 2^64 случайных чисел.

Следующий пример демонстрирует этот шаблон:

# Compile this example with --threads:on
import random
import threadpool

const spawns = 4
const numbers = 100000

proc randomSum(rand: Rand): int =
  var r = rand
  for i in 1..numbers:
    result += rand(1..10)

var r = initRand(2019)
var vals: array[spawns, FlowVar[int]]
for val in vals.mitems:
  val = spawn(randomSum(r))
  r.skipRandomNumbers()

for val in vals:
  echo ^val

См. также:

  • процедуру next
Исходный код Редактировать
proc rand(r: var Rand; max: Natural): int {...}{.gcsafe, locks: 0, raises: [],
    tags: [].}

Возвращает случайное целое число в диапазоне 0..max, используя заданное состояние.

См. также:

  • процедуру rand которая возвращает целое число, используя генератор случайных чисел по умолчанию
  • процедуру rand которая возвращает число с плавающей запятой
  • процедуру rand которая принимает срез
  • процедуру rand которая принимает целочисленный или диапазонный тип

Пример:

var r = initRand(123)
doAssert r.rand(100) == 0
doAssert r.rand(100) == 96
doAssert r.rand(100) == 66
Исходный код Редактировать
proc rand(max: int): int {...}{.gcsafe, locks: 0, raises: [], tags: [].}

Возвращает случайное целое число в диапазоне 0..max.

Если процедура randomize не была вызвана, последовательность случайных чисел, возвращаемых этой процедурой, всегда будет одинаковой.

Эта процедура использует генератор случайных чисел по умолчанию. Таким образом, она не потокобезопасна.

См. также:

  • процедуру rand которая возвращает целое число, используя предоставленное состояние
  • процедуру rand которая возвращает число с плавающей запятой
  • процедуру rand которая принимает срез
  • процедуру rand которая принимает целочисленный или диапазонный тип

Пример:

randomize(123)
doAssert rand(100) == 0
doAssert rand(100) == 96
doAssert rand(100) == 66
Исходный код Редактировать
proc rand(r: var Rand; max: range[0.0 .. high(float)]): float {...}{.gcsafe,
    locks: 0, raises: [], tags: [].}

Возвращает случайное число с плавающей запятой в диапазоне 0.0..max, используя заданное состояние.

См. также:

  • процедуру rand которая возвращает число с плавающей запятой, используя генератор случайных чисел по умолчанию
  • процедуру rand которая возвращает целое число
  • процедуру rand которая принимает срез
  • процедуру rand которая принимает целочисленный или диапазонный тип

Пример:

var r = initRand(234)
let f = r.rand(1.0)
## f = 8.717181376738381e-07
Исходный код Редактировать
proc rand(max: float): float {...}{.gcsafe, locks: 0, raises: [], tags: [].}

Возвращает случайное число с плавающей запятой в диапазоне 0.0..max.

Если процедура randomize не была вызвана, последовательность случайных чисел, возвращаемых этой процедурой, всегда будет одинаковой.

Эта процедура использует генератор случайных чисел по умолчанию. Таким образом, она не потокобезопасна.

См. также:

  • процедуру rand которая возвращает число с плавающей запятой, используя предоставленное состояние
  • процедуру rand которая возвращает целое число
  • процедуру rand которая принимает срез
  • процедуру rand которая принимает целочисленный или диапазонный тип

Пример:

randomize(234)
let f = rand(1.0)
## f = 8.717181376738381e-07
Исходный код Редактировать
proc rand[T: Ordinal or SomeFloat](r: var Rand; x: HSlice[T, T]): T

Для среза a..b, возвращает значение в диапазоне a..b, используя заданное состояние.

Допустимые типы для T — целые числа, числа с плавающей запятой и перечисления без пропусков.

См. также:

  • процедуру rand которая принимает срез и использует генератор случайных чисел по умолчанию
  • процедуру rand которая возвращает целое число
  • процедуру rand которая возвращает число с плавающей запятой
  • процедуру rand которая принимает целочисленный или диапазонный тип

Пример:

var r = initRand(345)
doAssert r.rand(1..6) == 4
doAssert r.rand(1..6) == 4
doAssert r.rand(1..6) == 6
let f = r.rand(-1.0 .. 1.0)
## f = 0.8741183448756229
Исходный код Редактировать
proc rand[T: Ordinal or SomeFloat](x: HSlice[T, T]): T

Для среза a..b, возвращает значение в диапазоне a..b.

Допустимые типы для T — целые числа, числа с плавающей запятой и перечисления без пропусков.

Если процедура randomize не была вызвана, последовательность случайных чисел, возвращаемых этой процедурой, всегда будет одинаковой.

Эта процедура использует генератор случайных чисел по умолчанию. Таким образом, она не потокобезопасна.

См. также:

  • процедуру rand которая принимает срез и использует предоставленное состояние
  • процедуру rand которая возвращает целое число
  • процедуру rand которая возвращает число с плавающей запятой
  • процедуру rand которая принимает целочисленный или диапазонный тип

Пример:

randomize(345)
doAssert rand(1..6) == 4
doAssert rand(1..6) == 4
doAssert rand(1..6) == 6
Исходный код Редактировать
proc rand[T: SomeInteger](t: typedesc[T]): T

Возвращает случайное целое число в диапазоне low(T)..high(T).

Если процедура randomize не была вызвана, последовательность случайных чисел, возвращаемых этой процедурой, всегда будет одинаковой.

Эта процедура использует генератор случайных чисел по умолчанию. Таким образом, она не потокобезопасна.

См. также:

  • процедуру rand которая возвращает целое число
  • процедуру rand которая возвращает число с плавающей запятой
  • процедуру rand которая принимает срез

Пример:

randomize(567)
doAssert rand(int8) == 55
doAssert rand(int8) == -42
doAssert rand(int8) == 43
doAssert rand(uint32) == 578980729'u32
doAssert rand(uint32) == 4052940463'u32
doAssert rand(uint32) == 2163872389'u32
doAssert rand(range[1..16]) == 11
doAssert rand(range[1..16]) == 4
doAssert rand(range[1..16]) == 16
Исходный код Редактировать
proc sample[T](r: var Rand; s: set[T]): T

Возвращает случайный элемент из множества s, используя заданное состояние.

См. также:

  • процедуру sample которая использует генератор случайных чисел по умолчанию
  • процедуру sample для открытых массивов
  • процедуру sample которая использует функцию кумулятивного распределения

Пример:

var r = initRand(987)
let s = {1, 3, 5, 7, 9}
doAssert r.sample(s) == 5
doAssert r.sample(s) == 7
doAssert r.sample(s) == 1
Исходный код Редактировать
proc sample[T](s: set[T]): T

Возвращает случайный элемент из множества s.

Если процедура randomize не была вызвана, порядок результатов этой процедуры всегда будет одинаковым.

Эта процедура использует генератор случайных чисел по умолчанию. Таким образом, она не потокобезопасна.

См. также:

  • процедуру sample которая использует предоставленное состояние
  • процедуру sample для открытых массивов
  • процедуру sample которая использует функцию кумулятивного распределения

Пример:

randomize(987)
let s = {1, 3, 5, 7, 9}
doAssert sample(s) == 5
doAssert sample(s) == 7
doAssert sample(s) == 1
Исходный код Редактировать
proc sample[T](r: var Rand; a: openArray[T]): T

Возвращает случайный элемент из a, используя заданное состояние.

См. также:

  • процедуру sample которая использует генератор случайных чисел по умолчанию
  • процедуру sample которая использует функцию кумулятивного распределения
  • процедуру sample для множеств

Пример:

let marbles = ["red", "blue", "green", "yellow", "purple"]
var r = initRand(456)
doAssert r.sample(marbles) == "blue"
doAssert r.sample(marbles) == "yellow"
doAssert r.sample(marbles) == "red"
Исходный код Редактировать
proc sample[T](a: openArray[T]): T

Возвращает случайный элемент из a.

Если randomize не был вызван, порядок результатов этой функции всегда будет одинаковым.

Эта функция использует генератор случайных чисел по умолчанию. Таким образом, она не потокобезопасна.

См. также:

  • функцию sample, которая использует предоставленное состояние
  • функцию sample, которая использует функцию кумулятивного распределения
  • функцию sample для множеств

Пример:

let marbles = ["red", "blue", "green", "yellow", "purple"]
randomize(456)
doAssert sample(marbles) == "blue"
doAssert sample(marbles) == "yellow"
doAssert sample(marbles) == "red"
Исходный код Редактировать
proc sample[T, U](r: var Rand; a: openArray[T]; cdf: openArray[U]): T

Возвращает элемент из a с использованием функции кумулятивного распределения (CDF) и заданного состояния.

Аргумент cdf не обязательно должен быть нормирован, и он может содержать любой тип элементов, которые могут быть преобразованы в float. Он должен иметь такую же длину, как и a. Каждый элемент в cdf должен быть больше или равен предыдущему элементу.

В качестве аргумента cdf можно использовать результат вызова функции cumsum и возвращаемое значение функции cumsummed, обе из которых находятся в модуле math.

См. также:

  • функцию sample, которая также использует CDF, но использует генератор случайных чисел по умолчанию
  • функцию sample, которая не использует CDF
  • функцию sample для множеств

Пример:

from math import cumsummed

let marbles = ["red", "blue", "green", "yellow", "purple"]
let count = [1, 6, 8, 3, 4]
let cdf = count.cumsummed
var r = initRand(789)
doAssert r.sample(marbles, cdf) == "red"
doAssert r.sample(marbles, cdf) == "green"
doAssert r.sample(marbles, cdf) == "blue"
Исходный код Редактировать
proc sample[T, U](a: openArray[T]; cdf: openArray[U]): T

Возвращает элемент из a с использованием функции кумулятивного распределения (CDF).

Эта функция работает аналогично sample[T, U](Rand, openArray[T], openArray[U]). Для получения более подробной информации см. документацию этой функции.

Если randomize не был вызван, порядок результатов этой функции всегда будет одинаковым.

Эта функция использует генератор случайных чисел по умолчанию. Таким образом, она не потокобезопасна.

См. также:

  • функцию sample, которая также использует CDF, но использует предоставленное состояние
  • функцию sample, которая не использует CDF
  • функцию sample для множеств

Пример:

from math import cumsummed

let marbles = ["red", "blue", "green", "yellow", "purple"]
let count = [1, 6, 8, 3, 4]
let cdf = count.cumsummed
randomize(789)
doAssert sample(marbles, cdf) == "red"
doAssert sample(marbles, cdf) == "green"
doAssert sample(marbles, cdf) == "blue"
Исходный код Редактировать
proc gauss(r: var Rand; mu = 0.0; sigma = 1.0): float {...}{.raises: [], tags: [].}
Возвращает гауссово случайное значение со средним значением mu и стандартным отклонением sigma с использованием заданного состояния. Исходный код Редактировать
proc gauss(mu = 0.0; sigma = 1.0): float {...}{.raises: [], tags: [].}

Возвращает гауссово случайное значение со средним значением mu и стандартным отклонением sigma.

Если randomize не был вызван, порядок результатов этой функции всегда будет одинаковым.

Эта функция использует генератор случайных чисел по умолчанию. Таким образом, она не потокобезопасна.

Исходный код Редактировать
proc initRand(seed: int64): Rand {...}{.raises: [], tags: [].}

Инициализирует новое состояние Rand с использованием заданного значения.

seed не должно быть равно нулю. Предоставление определенного значения приведет к одинаковым результатам для этого значения каждый раз.

Полученное состояние не зависит от состояния генератора случайных чисел по умолчанию.

См. также:

  • функцию randomize, которая принимает значение для генератора случайных чисел по умолчанию
  • функцию randomize, которая инициализирует генератор случайных чисел по умолчанию с использованием текущего времени

Пример:

from times import getTime, toUnix, nanosecond

var r1 = initRand(123)

let now = getTime()
var r2 = initRand(now.toUnix * 1_000_000_000 + now.nanosecond)
Исходный код Редактировать
proc randomize(seed: int64) {...}{.gcsafe, locks: 0, raises: [], tags: [].}

Инициализирует генератор случайных чисел по умолчанию заданным значением.

seed не должно быть равно нулю. Предоставление определенного значения приведет к одинаковым результатам для этого значения каждый раз.

См. также:

  • функцию initRand
  • функцию randomize, которая использует текущее время вместо этого

Пример:

from times import getTime, toUnix, nanosecond

randomize(123)

let now = getTime()
randomize(now.toUnix * 1_000_000_000 + now.nanosecond)
Исходный код Редактировать
proc shuffle[T](r: var Rand; x: var openArray[T])

Перемешивает последовательность элементов на месте с использованием заданного состояния.

См. также:

  • функцию shuffle, которая использует генератор случайных чисел по умолчанию

Пример:

var cards = ["Ace", "King", "Queen", "Jack", "Ten"]
var r = initRand(678)
r.shuffle(cards)
doAssert cards == ["King", "Ace", "Queen", "Ten", "Jack"]
Исходный код Редактировать
proc shuffle[T](x: var openArray[T])

Перемешивает последовательность элементов на месте.

Если randomize не был вызван, порядок результатов этой функции всегда будет одинаковым.

Эта функция использует генератор случайных чисел по умолчанию. Таким образом, она не потокобезопасна.

См. также:

  • функцию shuffle, которая использует предоставленное состояние

Пример:

var cards = ["Ace", "King", "Queen", "Jack", "Ten"]
randomize(678)
shuffle(cards)
doAssert cards == ["King", "Ace", "Queen", "Ten", "Jack"]
Исходный код Редактировать
proc randomize() {...}{.gcsafe, locks: 0, raises: [], tags: [TimeEffect].}

Инициализирует генератор случайных чисел по умолчанию значением, основанным на текущем времени.

Вызывать эту функцию нужно только один раз, и её следует вызвать перед первым использованием функций из этого модуля, которые используют генератор случайных чисел по умолчанию.

Примечание: Не работает для NimScript.

См. также:

  • функцию randomize, которая принимает значение
  • функцию initRand
Исходный код Редактировать

© 2006–2021 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/random.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API