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!
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 many Random
objects with the same seed value, producing the same result. The Thread.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:
var randomNumbers = new Dictionary<int, int>();
var random = new Random(); // Re-use this, don't keep creating new ones.
foreach (var s in Enumerable.Range(1, 500))
{
var rand = random.Next(1, 6);
// ...
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 love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With