класс Random
Random предоставляет интерфейс к псевдослучайному генератору чисел Руби, или PRNG. PRNG генерирует детерминированную последовательность битов, приближающую истинную случайность. Последовательность может быть представлена целыми числами, числами с плавающей точкой или двоичными строками.
Генератор может быть инициализирован либо сгенерированным системой, либо заданным пользователем значением семян с помощью ::srand.
Метод класса #rand предоставляет базовые функциональные возможности Kernel#rand вместе с лучшим обращением с числами с плавающей точкой. Оба являются интерфейсами к Random::DEFAULT, системному PRNG Руби.
::new создаст новый PRNG с состоянием, независимым от Random::DEFAULT, что позволит существовать нескольким генераторам с различными значениями семян или позициями в последовательности одновременно. Объекты Random могут быть закодированы, что позволяет сохранять и возобновлять последовательности.
PRNG в настоящее время реализованы как модифицированный Mersenne Twister с периодом 2**19937-1.
Константы
- DEFAULT
-
Прямой доступ к псевдослучайному генератору чисел (PRNG) Руби.
Публичные методы класса
static VALUE
random_init(int argc, VALUE *argv, VALUE obj)
{
VALUE vseed;
rb_random_t *rnd = get_rnd(obj);
if (argc == 0) {
rb_check_frozen(obj);
vseed = random_seed();
}
else {
rb_scan_args(argc, argv, "01", &vseed);
rb_check_copyable(obj, vseed);
}
rnd->seed = rand_init(&rnd->mt, vseed);
return obj;
} Создаёт новый PRNG, используя seed для установки начального состояния. Если seed опущено, генератор инициализируется с помощью ::new_seed.
См. ::srand для получения дополнительной информации об использовании значений семян.
static VALUE
random_seed(void)
{
uint32_t buf[DEFAULT_SEED_CNT];
fill_random_seed(buf);
return make_seed_value(buf);
} Возвращает произвольное значение семян. Оно используется методом ::new, когда значение семян не указано в качестве аргумента.
Random.new_seed #=> 115032730400174366788466674494640623225
static VALUE
random_s_rand(int argc, VALUE *argv, VALUE obj)
{
return rand_random(argc, argv, rand_start(&default_rand));
} Псевдоним Random::DEFAULT.rand.
static VALUE
rb_f_srand(int argc, VALUE *argv, VALUE obj)
{
VALUE seed, old;
rb_random_t *r = &default_rand;
if (argc == 0) {
seed = random_seed();
}
else {
rb_scan_args(argc, argv, "01", &seed);
}
old = r->seed;
r->seed = rand_init(&r->mt, seed);
return old;
} Инициализирует системный псевдослучайный генератор чисел, Random::DEFAULT, значением number. Возвращает предыдущее значение семян.
Если number опущено, генератор инициализируется с использованием источника энтропии, предоставленного операционной системой (если доступен /dev/urandom в системах Unix или криптографический провайдер RSA в Windows), который затем комбинируется со временем, идентификатором процесса и номером последовательности.
srand может использоваться для обеспечения повторяющихся последовательностей псевдослучайных чисел между различными запусками программы. Установив семена на известное значение, программы могут быть сделаны детерминированными во время тестирования.
srand 1234 # => 268519324636777531569100071560086917274 [ rand, rand ] # => [0.1915194503788923, 0.6221087710398319] [ rand(10), rand(1000) ] # => [4, 664] srand 1234 # => 1234 [ rand, rand ] # => [0.1915194503788923, 0.6221087710398319]
Публичные методы экземпляра
static VALUE
random_equal(VALUE self, VALUE other)
{
rb_random_t *r1, *r2;
if (rb_obj_class(self) != rb_obj_class(other)) return Qfalse;
r1 = get_rnd(self);
r2 = get_rnd(other);
if (!RTEST(rb_funcall2(r1->seed, rb_intern("=="), 1, &r2->seed))) return Qfalse;
if (memcmp(r1->mt.state, r2->mt.state, sizeof(r1->mt.state))) return Qfalse;
if ((r1->mt.next - r1->mt.state) != (r2->mt.next - r2->mt.state)) return Qfalse;
if (r1->mt.left != r2->mt.left) return Qfalse;
return Qtrue;
} Возвращает true, если два генератора имеют одинаковое внутреннее состояние, иначе false. Эквивалентные генераторы будут возвращать ту же последовательность псевдослучайных чисел. Два генератора, как правило, будут иметь одинаковое состояние только в том случае, если они были инициализированы с одинаковым значением семян
Random.new == Random.new # => false Random.new(1234) == Random.new(1234) # => true
и имеют одинаковую историю вызовов.
prng1 = Random.new(1234) prng2 = Random.new(1234) prng1 == prng2 # => true prng1.rand # => 0.1915194503788923 prng1 == prng2 # => false prng2.rand # => 0.1915194503788923 prng1 == prng2 # => true
static VALUE
random_bytes(VALUE obj, VALUE len)
{
return rb_random_bytes(obj, NUM2LONG(rb_to_int(len)));
} Возвращает случайную двоичную строку, содержащую size байтов.
random_string = Random.new.bytes(10) # => "\xD7:R\xAB?\x83\xCE\xFAkO" random_string.size # => 10
static VALUE
random_rand(int argc, VALUE *argv, VALUE obj)
{
return rand_random(argc, argv, get_rnd(obj));
} Если max является целым числом, rand возвращает случайное целое число, большее или равное нулю и меньшее max. В отличие от Kernel#rand, если max является отрицательным целым числом или нулём, rand генерирует ArgumentError.
prng = Random.new prng.rand(100) # => 42
Если max является числом с плавающей точкой, rand возвращает случайное число с плавающей точкой между 0,0 и max, включая 0,0 и исключая max.
prng.rand(1.5) # => 1.4600282860034115
Если max является диапазоном, rand возвращает случайное число, где range.member?(number) == true.
prng.rand(5..9) # => one of [5, 6, 7, 8, 9] prng.rand(5...9) # => one of [5, 6, 7, 8] prng.rand(5.0..9.0) # => between 5.0 and 9.0, including 9.0 prng.rand(5.0...9.0) # => between 5.0 and 9.0, excluding 9.0
И начальное, и конечное значения диапазона должны иметь методы вычитания (-) и сложения (+), иначе rand сгенерирует ArgumentError.
static VALUE
random_get_seed(VALUE obj)
{
return get_rnd(obj)->seed;
} Возвращает значение семян, использованное для инициализации генератора. Это может быть использовано для инициализации другого генератора с тем же состоянием в более позднее время, заставляя его генерировать ту же последовательность чисел.
prng1 = Random.new(1234) prng1.seed #=> 1234 prng1.rand(100) #=> 47 prng2 = Random.new(prng1.seed) prng2.rand(100) #=> 47
Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.