exponenta event banner

Управление генерацией случайных чисел

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

(Псевдо) Случайные числа в MATLAB происходят от rand, randi, и randn функции. Многие другие функции называют эти три, но это фундаментальные строительные блоки. Все три зависят от одного общего генератора случайных чисел, которым можно управлять с помощью rng.

Важно понимать, что «случайные» числа в MATLAB вовсе не непредсказуемы, а генерируются детерминированным алгоритмом. Алгоритм разработан достаточно сложным, чтобы его выход представлялся независимой случайной последовательностью тому, кто не знает алгоритма, и мог пройти различные статистические тесты случайности. Функция, которая представлена здесь, предоставляет способы использовать преимущества детерминизма для

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

  • гарантировать использование различных случайных чисел в повторных вычислениях

и использовать преимущества очевидной случайности для обоснования объединения результатов отдельных вычислений.

«Начать заново»

Если посмотреть на выходные данные из rand, randi, или randn в новой сессии MATLAB вы заметите, что они возвращают одинаковые последовательности чисел каждый раз при перезапуске MATLAB. Часто полезно иметь возможность сбросить генератор случайных чисел в это состояние запуска без фактического перезапуска MATLAB. Например, можно повторить вычисление, включающее случайные числа, и получить тот же результат.

rng предоставляет очень простой способ вернуть генератору случайных чисел настройки по умолчанию.

rng default
rand % returns the same value as at startup
ans = 0.8147

Каковы настройки случайных чисел по умолчанию, с которыми запускается MATLAB, или rng default дает? При звонке rng без входов видно, что это алгоритм генератора Мерсенна Твистера, затравленный 0.

rng
ans = struct with fields:
     Type: 'twister'
     Seed: 0
    State: [625x1 uint32]

Ниже вы увидите более подробно, как использовать вышеуказанные выходные данные, включая State для управления и изменения того, как MATLAB генерирует случайные числа. Пока это служит способом увидеть, какой генератор rand, randi, и randn используются в настоящее время.

Неповторяемость

Каждый раз, когда вы звоните rand, randi, или randnони извлекают новое значение из их общего генератора случайных чисел, и последовательные значения могут рассматриваться как статистически независимые. Но как упоминалось выше, каждый раз при перезапуске MATLAB эти функции сбрасываются и возвращают те же последовательности чисел. Очевидно, что вычисления, использующие одни и те же «случайные» числа, нельзя считать статистически независимыми. Поэтому, когда необходимо объединить вычисления, выполненные в двух или более сессиях MATLAB, как если бы они были статистически независимыми, нельзя использовать настройки генератора по умолчанию.

Один простой способ избежать повторения одних и тех же случайных чисел в новом сеансе MATLAB - выбрать другое начальное число для генератора случайных чисел. rng дает вам простой способ сделать это, создав начальное число на основе текущего времени.

rng shuffle
rand
ans = 0.1918

Каждый раз, когда вы используете 'shuffle', он повторно загружает генератор с другим начальным числом. Вы можете позвонить rng без входных данных, чтобы увидеть, какое семя он на самом деле использовал.

rng
ans = struct with fields:
     Type: 'twister'
     Seed: 355976173
    State: [625x1 uint32]

rng shuffle % creates a different seed each time
rng
ans = struct with fields:
     Type: 'twister'
     Seed: 355976176
    State: [625x1 uint32]

rand
ans = 0.9547

'shuffle' является очень простым способом повторного создания генератора случайных чисел. Вы можете подумать, что это хорошая идея, или даже необходимо, использовать ее, чтобы получить «истинную» случайность в MATLAB. Однако для большинства целей нет необходимости использовать 'shuffle' вообще. Выбор начального значения на основе текущего времени не улучшает статистические свойства значений, которые вы получите от rand, randi, и randn, и не делает их «более случайными» в каком-либо реальном смысле. Несмотря на то, что совершенно нормально повторять генератор каждый раз, когда вы запускаете MATLAB, или перед тем, как запустить какой-то большой расчет, включающий случайные числа, на самом деле, не очень хорошая идея, чтобы повторять генератор слишком часто в течение сессии, потому что это может повлиять на статистические свойства ваших случайных чисел.

Что 'shuffle' обеспечивает способ избежать повторения одних и тех же последовательностей значений. Иногда это критично, иногда просто «приятно», но часто это вообще не важно. Помните, что если вы используете 'shuffle', возможно, вы захотите сохранить затравку, которая rng создан таким образом, чтобы можно было повторить вычисления позже. Вы увидите, как это сделать ниже.

Больший контроль за повторяемостью и неповторяемостью

До сих пор вы видели, как сбросить генератор случайных чисел к его настройкам по умолчанию и повторно использовать начальное число, созданное с использованием текущего времени. rng также предоставляет способ повторного заполнения с использованием определенного начального числа.

Можно использовать одно и то же начальное число несколько раз, чтобы повторить одни и те же вычисления. Например, если запустить этот код дважды...

rng(1) % the seed is any non-negative integer < 2^32
x = randn(1,5)
x = 1×5

   -0.6490    1.1812   -0.7585   -1.1096   -0.8456

rng(1)
x = randn(1,5)
x = 1×5

   -0.6490    1.1812   -0.7585   -1.1096   -0.8456

... вы получаете точно такие же результаты. Это можно сделать, чтобы воссоздать x после очистки, чтобы можно было повторить то, что происходит в последующих расчетах, которые зависят от x, используя эти конкретные значения.

С другой стороны, можно выбрать различные начальные значения, чтобы избежать повторения одних и тех же вычислений. Например, если этот код выполняется в одном сеансе MATLAB...

rng(2)
x2 = sum(randn(50,1000),1); % 1000 trials of a random walk

и этот код в другом...

rng(3)
x3 = sum(randn(50,1000),1);

... Вы можете объединить два результата и быть уверены, что они не просто те же результаты повторяются дважды.

x = [x2 x3];

Как и с 'shuffle' существует предостережение при повторной установке генератора случайных чисел MATLAB, поскольку это влияет на все последующие выходные данные из rand, randi, и randn. Если не требуется повторяемость или уникальность, обычно рекомендуется просто генерировать случайные значения без повторного использования генератора. Если вам действительно нужно переустановить генератор, это обычно лучше всего сделать в командной строке или в месте в коде, которое нелегко пропустить.

Выбор типа генератора

Можно не только повторно создать генератор случайных чисел, как показано выше, но и выбрать тип генератора случайных чисел, который требуется использовать. Различные типы генераторов создают различные последовательности случайных чисел, и можно, например, выбрать определенный тип из-за его статистических свойств. Также может потребоваться повторное создание результатов из более старой версии MATLAB, в которой использовался другой тип генератора по умолчанию.

Еще одна распространенная причина выбора типа генератора заключается в том, что вы пишете проверочный тест, который генерирует «случайные» входные данные, и вы должны гарантировать, что ваш тест всегда может ожидать точно такой же предсказуемый результат. При звонке rng при помощи начального числа перед созданием входных данных он повторно загружает генератор случайных чисел. Но если тип генератора был по какой-то причине изменен, то выход из rand, randi, и randn не будет тем, чего вы ожидаете от этого семени. Поэтому для 100% -ной повторяемости можно также указать тип генератора.

Например,

rng(0,'twister')

причины rand, randi, и randn чтобы использовать алгоритм генератора Мерсенна Твистера, после заполнения его 0.

Используя 'combRecursive'

rng(0,'combRecursive')

выбирает алгоритм комбинированного множественного рекурсивного генератора, который поддерживает некоторые параллельные функции, которых не имеет Мерсенн Твистер.

Эта команда

rng(0,'v4')

выбирает алгоритм генератора, который использовался по умолчанию в MATLAB 4.0.

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

rng default

Однако, поскольку настройки генератора случайных чисел по умолчанию могут изменяться между выпусками MATLAB, использование 'default' не гарантирует предсказуемых результатов в долгосрочной перспективе. 'default' является удобным способом сброса генератора случайных чисел, но для ещё большей предсказуемости укажите тип генератора и начальное число.

С другой стороны, когда вы работаете в интерактивном режиме и нуждаетесь в повторяемости, это проще и обычно достаточно, чтобы позвонить rng только с семенем.

Сохранение и восстановление параметров генератора случайных чисел

Запрос rng без входных данных возвращает скалярную структуру с полями, которые содержат две части уже описанной информации: тип генератора и целое число, с помощью которого генератор был повторно загружен в последний раз.

s = rng
s = struct with fields:
     Type: 'twister'
     Seed: 0
    State: [625x1 uint32]

Третье поле, State, содержит копию вектора текущего состояния генератора. Этот вектор состояния является информацией, которую генератор поддерживает внутри, чтобы генерировать следующее значение в своей последовательности случайных чисел. Каждый раз, когда вы звоните rand, randi, или randnгенератор, которым они делятся, обновляет свое внутреннее состояние. Таким образом, вектор состояния в структуре настроек возвращается rng содержит информацию, необходимую для повторения последовательности, начиная с точки захвата состояния.

Хотя просто иметь возможность видеть этот вывод является информативным, rng также принимает структуру настроек в качестве входных данных, чтобы можно было сохранить настройки, включая вектор состояния, и восстановить их позже для повторения вычислений. Поскольку настройки содержат тип генератора, вы будете точно знать, что вы получаете, и поэтому «позже» может означать что-либо от моментов позже в той же сессии MATLAB, до лет (и нескольких выпусков MATLAB) позже. Можно повторить результаты из любой точки в последовательности случайных чисел, в которой были сохранены настройки генератора. Например,

x1 = randn(10,10); % move ahead in the random number sequence
s = rng;           % save the settings at this point
x2 = randn(1,5)
x2 = 1×5

    0.8404   -0.8880    0.1001   -0.5445    0.3035

x3 = randn(5,5);   % move ahead in the random number sequence
rng(s);            % return the generator back to the saved state
x2 = randn(1,5)    % repeat the same numbers
x2 = 1×5

    0.8404   -0.8880    0.1001   -0.5445    0.3035

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

Наиболее распространенным способом использования структуры настроек является восстановление состояния генератора. Однако, поскольку структура содержит не только состояние, но также тип генератора и начальное число, это также удобный способ временного переключения типов генератора. Например, если необходимо создать значения с помощью одного из устаревших генераторов из MATLAB 5.0, можно сохранить текущие настройки одновременно с переключением на использование старого генератора...

previousSettings = rng(0,'v5uniform')
previousSettings = struct with fields:
     Type: 'twister'
     Seed: 0
    State: [625x1 uint32]

... а затем восстановите исходные параметры позже.

rng(previousSettings)

Не следует изменять содержимое ни одного из полей в структуре параметров настройки. В частности, не следует строить собственный вектор состояния или даже зависеть от формата состояния генератора.

Написание проще, гибче, код

rng позволяет выполнять одно из следующих действий:

  • повторно создать генератор случайных чисел, или

  • сохранить и восстановить настройки генератора случайных чисел

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

Если можно избежать указания типа генератора, код автоматически адаптируется к случаям, когда требуется использовать другой генератор, и автоматически получает преимущества от улучшенных свойств в новом типе генератора случайных чисел по умолчанию.

rng и RandStream

rng обеспечивает удобный способ управления генерацией случайных чисел в MATLAB для наиболее распространенных потребностей. Однако более сложные ситуации, включающие в себя множество потоков случайных чисел и параллельную генерацию случайных чисел, требуют более сложного инструмента. RandStream класс - это этот инструмент, и он предоставляет самый мощный способ управления генерацией случайных чисел. Эти два инструмента дополняют друг друга, rng обеспечение гораздо более простого и краткого синтаксиса, который построен поверх гибкости RandStream.