tags:

views:

120

answers:

2

Is there a way to store the current state of the built in pseudo-random number generator in Perl so that when my program is run again, it can pick up the sequence from where it left off rather than starting with a new sequence?

Right now, I am storing where I am as well as the initial seed and then throwing away the initial segment which I have already seen using something similar to:

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

For example:

srand 0x18;
my @v = map { rand } 1 .. 5;

Later:

consume_upto_n(0x18, 3);
my @z = map { rand } 3 .. 5;

Then, $z[0] == $v[2], $z[1] == $v[3] etc.

+6  A: 

I don't think the built-in rand allows you to do that. But you can use a substitute rand. For example, Math::Random::MT::Auto allows you to serialize its objects (presumably including $MRMA::PRNG, which is the object that gets used by its replacement rand).

I'm not quite sure what the point is, though. If it's a reasonably random sequence, how can you tell whether you're continuing that sequence or starting a new one?

cjm
@cjm This is for simulation purposes. Say I have a simulation that requires 10,000 draws. The quality of the random number generator does not matter much but the ability to replicate (for any given `perl` + OS + app version combination) a given sequence is important. I want to be able to interrupt it in the middle and pick up from where we left off. This way, I can replicate the exact sequence of events later on by just storing the initial seed.
Sinan Ünür
Sinan: There's multiple things you're asking for: Being able to continue the sequence at some arbitrary point and being able to restart the exact same point. Both can be done using one of the Math::Random::* modules but from a cursory inspection of the perl sources, this cannot be (easily) done with the builtin rand() even from XS! (Perl may call c library's rand() as part of its rand() and the implementation seems platform dependent.)
tsee
@cjm and @tsee It is better not to have to rely on the built in `rand` anyway.
Sinan Ünür
A: 

As of perl 5.13.4, srand returns the seed:

srand() now returns the seed

This allows programs that need to have repeatable results to not have to come up with their own seed generating mechanism. Instead, they can use srand() and somehow stash the return for future use. Typical is a test program which has too many combinations to test comprehensively in the time available to it each run. It can test a random subset each time, and should there be a failure, log the seed used for that run so that it can later be used to reproduce the exact results.

Sinan Ünür