Ruby中的可重复随机性

Ruby中的可重复随机性,ruby,random,srand,Ruby,Random,Srand,我知道我可以通过使用种子调用srand来“重新启动”我的rand调用,但这肯定会影响其他库方法(包括加密方法)将来对rand的调用吗 我如何在某些地方重复我的随机性,并且仍然确保我的其余代码不受影响?好吧,您可以实现自己的PRNG,而不使用系统版本。关于如何做到这一点,有大量的文献,从最简单的到最简单的 事实上,由于Ruby是开源的,您实际上可以(参见random.c)了解它如何使用与系统版本不同的信息来实现随机数和重新实现随机数。如果您使用的是JRuby,您只需实例化java.util.ran

我知道我可以通过使用种子调用
srand
来“重新启动”我的
rand
调用,但这肯定会影响其他库方法(包括加密方法)将来对
rand
的调用吗


我如何在某些地方重复我的随机性,并且仍然确保我的其余代码不受影响?

好吧,您可以实现自己的PRNG,而不使用系统版本。关于如何做到这一点,有大量的文献,从最简单的到最简单的


事实上,由于Ruby是开源的,您实际上可以(参见
random.c
)了解它如何使用与系统版本不同的信息来实现随机数和重新实现随机数。

如果您使用的是JRuby,您只需实例化
java.util.random
使用gem即可。

(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
兰德():

…Kernel::srand可用于确保程序不同运行之间的可重复随机数序列

srand():

将伪随机数生成器种子设定为number.to_i.abs…的值。。。通过将种子设置为已知值,可以在测试期间确定脚本

您可以存储种子值和用户进行的迭代次数,然后在以后的时间使用该值重新设定种子,然后循环他们之前使用该值跳过先前值的次数,并在序列中确定下一个值。这是我所知道的恢复序列的唯一方法。如果您担心其他例程/线程,那么在设置srand之前,获取原始种子并存储它,然后获取下一个数字,然后恢复原始种子

如果你担心影响依赖它的其他例程的随机性,我认为这些例程的作者应该做些事情来确保他们处理的是一个真正的随机种子。你真的只能关心你自己的代码,而不能破坏系统。除此之外,责任就归他们了。

(在ruby 1.9.3中)使用了一个更简单的解决方案


您需要使用
r=Random.new(seed)
来获取一个对象,您可以使用该对象来生成随机性调用
r.rand
。这是repeateble,只会影响对
r.rand
的调用,而不会影响
Kernel.rand

什么是“重复随机性”?如果某件事情是随机的,根据定义,它不应该是可重复的。也许可以解释一下你实际上想要实现什么(例如,你调用rand的目的)。他想把PRNG的所有状态放在一个对象中,这样就不会有其他线程(或幕后进程)可以窃取随机数并扰乱序列。@Brett:拥有一个可重复的伪随机数序列对于执行模拟(以及调试这些模拟)通常很重要。我的意思是我想以随机顺序向不同的人展示东西,但我希望每个人每次都能以相同的顺序看到这些项目。理想情况下,我希望这样做,而不保存为每个人随机分配的整个列表。这正是我的观点(我在问题中提到了这两个)。在我用seed调用了
srand
之后,任何未来的
rand
调用(无论是我调用它们还是其他库函数)都将是可预测的-在我用可预测的、可重复的seed调用srand之后,我失去了随机性。适用于具有
的早期Ruby版本,需要“backport”
,虽然它将比1.9.2中的本机类慢得多。我已经对
Random
类进行了后端口:只是
需要“后端口”