Why isn't Random() random? [duplicate]

2019-04-27 11:26发布

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!

标签: .net random
6条回答
\"骚年 ilove
2楼-- · 2019-04-27 12:03

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.

查看更多
Evening l夕情丶
3楼-- · 2019-04-27 12:12

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

查看更多
放荡不羁爱自由
4楼-- · 2019-04-27 12:14

The random number generator is based partially on the system clock, and C# is too darn fast churning them out...

查看更多
ゆ 、 Hurt°
5楼-- · 2019-04-27 12:15

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);
    // ...
查看更多
We Are One
6楼-- · 2019-04-27 12:22

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

查看更多
在下西门庆
7楼-- · 2019-04-27 12:27

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.

查看更多
登录 后发表回答