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

В этом примере показано, как использовать 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 является выбор другого seed для генератора случайных чисел. rng дает вам легкий способ сделать это, создав seed на основе текущего времени.

rng shuffle
rand
ans = 0.1918

Каждый раз, когда вы используете 'shuffle', он перезапускает генератор с другим seed. Можно вызвать 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' вообще. Выбор seed на основе текущего времени не улучшает статистические свойства значений, которые вы получите от rand, randi, и randn, и не делает их «более случайными» в каком-либо реальном смысле. Хотя совершенно нормально сбрасывать генератор каждый раз, когда вы запускаете MATLAB, или прежде чем вы запускаете какое-то большое вычисление со случайными числами, это на самом деле не является хорошей идеей, чтобы сбросить генератор слишком часто в течение сеанса, потому что это может повлиять на статистические свойства ваших случайных чисел.

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

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

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

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

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 с помощью seed перед созданием входных данных он перезапускает генератор случайных чисел. Но если тип генератора по какой-то причине был изменен, то выход из rand, randi, и randn не будет того, чего вы ожидаете от этого seed. Поэтому, чтобы быть 100% уверенным в повторяемости, можно также задать тип генератора.

Для примера,

rng(0,'twister')

причины rand, randi, и randn использовать алгоритм генератора Случайных Чисел Вихрь Мерсенна, после посева с 0.

Использование 'combRecursive'

rng(0,'combRecursive')

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

Эта команда

rng(0,'v4')

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

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

rng default

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

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

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

Вызывающие 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

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

Наиболее распространенным способом использования структуры параметров является восстановление состояния генератора. Однако, поскольку структура содержит не только состояние, но и тип генератора и seed, это также удобный способ временного переключения типов генератора. Например, если вам нужно создать значения с помощью одного из устаревших генераторов из 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 для наиболее распространенных нужд. Однако более сложные ситуации, связанные с несколькими потоками случайных чисел и параллельной генерацией случайных чисел, требуют более сложного инструмента. The RandStream класс является этим инструментом, и он предоставляет самый мощный способ управления генерацией случайных чисел. Эти два инструмента являются взаимодополняющими, с rng обеспечивая намного более простой и краткий синтаксис, который построен на верхнюю часть гибкости RandStream.