Keith Thompson said:
In your initial contribution to this thread, you wrote:
(Rod Pemberton wrote
] The algorithm which generates a semi-random or pseudo-random number
] sequence has some internal initial values. If you don't call
] srand(), the sequence will be semi-random but will be the same
] sequence every time you run your program. So, if you were to write
] a card playing program, you might call srand() at every shuffle to
] start a new semi-random sequence and call rand() to generate the
] deck of cards. The "randomness" comes from the algorithm in rand()
] not from the starting values in generated by srand().
My response was that it would make more sense to call, say,
srand(time(NULL)) exactly once at program startup, and use successive
values from the *same* pseudo-random sequence for successive shuffles.
You said I was wrong.
You seem to be claiming that calling srand() *again* for each shuffle
is somehow better than calling srand() exactly once at program startup
and generating all shuffles from the single resulting pseudo-random
sequence. (By "calling srand()", I mean "calling the srand function
with some appropriate argument, such as srand(time(NULL))".) Is that
in fact what you've been claiming? In what sense is calling srand()
repeatedly better than calling it only once? How is starting a new
pseudo-random sequence better than continuing to use the original one?
Rod is probably referring to the fact that any PRNG is going to be
periodic in output. I think his point is that it makes sense to switch
to a new "sequence" by re-seeding, before the period expires.
Note that he doesn't say you should call srand() before every call to
rand(), he says you should call it once per shuffle. That's probably
once for every 52 calls to rand(). And those 52 calls will happen
quickly, in succession, but then there's likely to be a fairly long
lag 'til the next rand() call (before which he proposes to reseed).
This might not necessarily be a bad idea, and might even improve
randomness provided the time taken for each game varies.
However, for the vast majority of other types applications, it is
likely to be a bad idea, since the time between calls to srand() may
be too predictable; and of course, if srand() is called too
frequently, the results probably won't be very random, since the
initial seeds to srand() are likely to be very similar to eachother.
To my mind, srand() every 52 times is still too frequent, considering
that a typical PRNG is likely to have a period of far greater than
52. Now, if you called srand() every 500 shuffles (assuming a fairly dumb
PRNG), then you might actually improve the randomness. This requires
that there's at least been enough time passed to change the seed (if
you're using time()), and is much more likely to improve randomness if
the periods of time between srand()s vary, themselves.
Still, I don't know that calling srand() every shuffle will hurt,
either (again, given varying times in game lengths): it probably
depends on the algorithm used by the PRNG.
I think typical implementations of rand() have long enough periods
that it still doesn't make much sense to do this. Several
implementations have periods of 2**32, in which case you'll never hit
the limit, no matter how many card games you play in your lifetime.
However, in the end, his suggestion of calling srand() for every
shuffle is no different from calling srand() only once, in a version
of the game that only allows you to play one hand.
-Micah