http://qs321.pair.com?node_id=120658

hopes has asked for the wisdom of the Perl Monks concerning the following question:

Hi to all!:
I would like to know how srand works.
In srand it is said this:
Do not call srand multiple times in your program unless you know exactly what you're doing and why you're doing it. The point of the function is to "seed" the rand function so that rand can produce a different sequence each time you run your program. Just do it once at the top of your program, or you won't get random numbers out of rand! but doesn't explain the extrange behaviour of
srand (time ^ ($$ + ($$ << 11))); print join ",", map { srand (time ^ ($$ + ($$ << 11))); $_=int(rand(10)) }(0..10);

Yes, I know I was told not to do that, but I want to know WHY...:-)
Why canīt I modify the seed during the execution?
When is srand evaluated, in runnig time or during the parsing?
Why does de code generates equal numbers?

Hopes

Replies are listed 'Best First'.
Re: srand and seed
by japhy (Canon) on Oct 23, 2001 at 03:54 UTC
    Calling srand() sets up the seed for the random number generator. Calling rand() then returns a random number in the sequence denoted by the seed.
    srand 10; $x = rand; srand 10; $y = rand;
    In that code, $x and $y will hold the same value. That is why YOUR code produces 11 identical values. Specifically, it runs so fast that time() never changes.

    _____________________________________________________
    Jeff[japhy]Pinyan: Perl, regex, and perl hacker.
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

Keep this in mind
by Fletch (Bishop) on Oct 23, 2001 at 04:36 UTC

    Anyone who considers arithmetical methods of producing random numbers is, of course, in a state of sin. -- John von Neumann

    The problem with calling it repeatedly is that you're not really making things any more random. rand only produces pseudorandom numbers based on the seed. You're not increasing the amount of entropy you're going to get out of it by multiple calls. In fact, if you're using things such as the process id in the seed you might even be reducing it (since the seeds could be `close' and put the generator in states that could overlap).

    Think of it this way: you've got a big book with pages full of numbers. srand tells what page in the book that rand should start reading from. Repeated calls to srand won't put any more randomness into the book, and might start reading numbers from pages you've already read.

    If you're really concerned about the randomness of your numbers then you want to forget rand all together and look into Math::TrulyRandom, or Crypt::Random if you have a /dev/random device available on your OS.

      I am doing a Monte Carlo simulation; it does 100 trials. Each trial takes 30 seconds. I call rand 2e7 times during each trial. I need uniform random numbers; duplicates are ok. The random numbers are a population to draw from (I am modeling sampling error) and a source for the Perl Cookbook Gausian Random number generator (I am also modeling measurement error) Should I call srand between trials? It seems that 30s is enough time for the source of the seed to change. Will the quality of the random numbers degrade after too many calls (e.g., 2e9 calls?)? I use active perl with win2000 so Math::TrulyRandom is not an option for me.
Re: srand and seed
by hopes (Friar) on Oct 23, 2001 at 04:03 UTC
    Thanks japhy; I didn't care of it.
    But, why are we advice not to set the seed more than once in a script?
    Oly for this?
    What happens if the seed doesn't have nothing with the time?
    srand ($$ ^ unpack "%L*", `ps axww | gzip`);
    Hopes
      This is because rand() is not really producing a random (as in throwing a dice) number. What rand() does, is calculate a value using a function with many arguments taken from your computer...

      Those arguments are there to increase the level of entropy. This makes the result of the function look as if it were indeed random, because you have very little control over the variables that are used by the rand() function.

      Whenever you reset the random seed with srand(), you're placing the generator in a state which might be too close to an earlier state. Since the time displacement between the two events can be very small, because the speed of your computer is comparatively high, the rest of the variables used by the random number generator might have the same (or very similar) values, so the rand() function will repeat an earlier sequence of numbers.