Повторяемая случайность в Ruby - PullRequest
5 голосов
/ 29 октября 2010

Я знаю, что могу "перезапустить" мои rand вызовы, вызвав srand с начальным числом, но, несомненно, это повлияет на будущие вызовы rand другими библиотечными методами, включая криптографические методы?

Как я могу повторить свою случайность в определенных местах и ​​при этом убедиться, что остальная часть моего кода не затронута?

Ответы [ 6 ]

2 голосов
/ 29 октября 2010

(Ruby 1.9.2) Вы можете сериализовать генератор случайных чисел, сохранить его в файле и предоставить файл с вашей программой.

Создать файл:

File.open('random_generator.marshal', 'w'){ |f| Marshal.dump(Random.new, f) }

использоватьгенератор случайных чисел в вашей программе:

f = File.open( 'random_generator.marshal', 'r' )
r = Marshal.load( f )
f.close

10.times{ puts r.rand } #repeatable
1 голос
/ 21 мая 2012

(в ruby ​​1.9.3) есть более простое решение, использующее Random.

Вам нужно использовать r = Random.new(seed), чтобы получить объект, который вы можете использовать для генерации случайности, вызывая r.rand. это повторяется и влияет только на вызовы r.rand, а не Kernel.rand.

1 голос
/ 29 октября 2010

Используйте простой-случайный драгоценный камень.

0 голосов
/ 30 октября 2010

rand ():

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

srand ():

Запускает генератор псевдослучайных чисел в значение number.to_i.abs.... Установив начальное значение для известного значения, сценарии можно сделать детерминированными во время тестирования ....

Вы можете сохранить свое начальное значение и количество итераций, выполненных пользователем,затем в последующем перезапустите это значение, затем зациклите количество раз, которое они использовали до того, как перейти к предыдущим значениям, и перейдите к следующему значению в последовательности.Это единственный известный мне способ попытаться восстановить последовательность.Если вас беспокоят другие процедуры / потоки, то возьмите исходное начальное число и сохраните его, прежде чем установить srand со своим, получите следующий номер, а затем восстановите исходное начальное число.другие подпрограммы, которые полагаются на это, я думаю, что авторы этих подпрограмм должны были что-то сделать, чтобы они имели дело с действительно случайным начальным числом.Вы действительно можете заботиться только о своем коде и не убивать систему.Помимо этого ответственность становится их.

0 голосов
/ 29 октября 2010

Если вы используете JRuby, вы можете просто создать экземпляр java.util.Random.

0 голосов
/ 29 октября 2010

Ну, вы могли бы реализовать свой собственный PRNG, который не использовал версию системы. Существует множество литературы на тему, как это сделать, от простейшего линейного конгруэнтного до мерсенновского твистера .

Фактически, поскольку Ruby является открытым исходным кодом, вы могли бы подсмотреть (см. random.c) о том, как он работает со случайными числами, и повторно реализовать это, используя информацию, отдельную от версии системы.

...