Possible Duplicate:
Why does this Random Number Generator not random?
I have this test program:
static void Main(string[] args)
{
var randomNumbers = new Dictionary<int, int>();
foreach (var s in Enumerable.Range(1, 500))
{
var rand = Rand5();
if (!randomNumbers.ContainsKey(rand))
randomNumbers.Add(rand, 1);
else
randomNumbers[rand] += 1;
}
randomNumbers
.ToList()
.ForEach(x => Console.WriteLine("{0}: {1}", x.Key, x.Value));
Console.ReadLine();
}
static int Rand5()
{
System.Threading.Thread.Sleep(1);
return new Random().Next(1, 6);
}
If I comment out System.Threading.Thread.Sleep(1);
, I get
5: 500
But if I uncomment that line, I do get random numbers.
2: 87
4: 94
1: 116
5: 108
3: 95
Why does the line of code matter? Thanks!
As others have said,
new Random()
seeds the random number generator from the current system time.I have an article describing this in more detail, including solutions to the problem, which you may find useful. Basically you want to use the same instance of
Random
multiple times - but observing that it's not thread-safe.If you don't seed the random, you get the same number as Random is a pseudo-random-generator
By using Thread.Sleep(1) you allow the timer to advance and to generate a new autogenerated-seed.
A way to "fix" is to create 1 Random object and reuse it (like some others also answered), or use a different random generator.
More info on http://msdn.microsoft.com/en-us/library/ctssatww.aspx
The random number generator is based partially on the system clock, and C# is too darn fast churning them out...
The
Random
type is seeded by default according to the current system time, which has finite granularity.Calling
new Random().Next(1, 6)
many times in rapid succession will thus construct manyRandom
objects with the same seed value, producing the same result. TheThread.Sleep(1)
call "solves" this problem by simply spacing the construcions farther apart in time, increasing the probability of distinct seed values.You need to retain a specific
Random
object from one call to the next:Cause it's using the clock as a seed for generating numbers and when you generate random numbers in that way, you get the same numbers
Any random number generator you use is a Pseudo-random number. This will always have a pre-defined seed value and is good for testing but not for implementing features of true randomness.
You should use a Quasi-random number sequence to generate random numbers or better still, Markovs chain to generate the best random numbers. If you plan on using one of those Random functions, you will not anything close to true randomness.