如何在Perl中存储伪随机生成器的状态?

Sin*_*nür 10 perl srand random-seed

有没有办法在Perl中存储内置的伪随机数生成器的当前状态,这样当我的程序再次运行时,它可以从它停止的位置获取序列而不是从新的序列开始?

现在,我存储的位置和初始种子一样,然后丢弃我已经看过的类似于以下内容的初始段:

sub consume_upto_n {
    my ($seed, $n) = @_;
    $n = 1 unless defined $n and $n >= 1;
    srand $seed;
    rand for 1 .. $n - 1;
    return;
}
Run Code Online (Sandbox Code Playgroud)

例如:

srand 0x18;
my @v = map { rand } 1 .. 5;
Run Code Online (Sandbox Code Playgroud)

后来:

consume_upto_n(0x18, 3);
my @z = map { rand } 3 .. 5;
Run Code Online (Sandbox Code Playgroud)

然后$z[0] == $v[2],$z[1] == $v[3]等等

cjm*_*cjm 6

我不认为内置rand允许你这样做.但你可以使用替代品rand.例如,Math :: Random :: MT :: Auto允许您序列化其对象(可能包括$MRMA::PRNG,它是替换使用的对象rand).

不过,我不太清楚重点是什么.如果它是一个合理的随机序列,你怎么知道你是继续这个序列还是开始一个新序列?

  • @cjm这是出于模拟目的.假设我有一个需要10,000次抽奖的模拟.随机数生成器的质量并不重要,但是复制(对于任何给定的`perl` + OS + app版本组合)给定序列的能力是重要的.我希望能够在中间中断它并从我们离开的地方继续.这样,我可以通过存储初始种子来复制事件的确切顺序. (4认同)

Sin*_*nür 1

从perl 5.13.4开始,srand返回种子

srand()现在返回种子

这使得需要具有可重复结果的程序不必提出自己的种子生成机制。相反,他们可以使用srand()并以某种方式储存回报以供将来使用。典型的情况是测试程序有太多组合,无法在每次运行的可用时间内进行全面测试。它可以每次测试一个随机子集,如果出现故障,记录用于该运行的种子,以便以后可以使用它来重现准确的结果。