new Random() 在多大程度上取决于时间? [英] How much does new Random() depends on time?

查看:62
本文介绍了new Random() 在多大程度上取决于时间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

昨天我在

如您所见,数字是从不同但相关的序列中选择的.正如 Random 上的 MSDN 所说,所选择的数字......对于实际用途来说是足够随机的."

Yesterday I wrote my first answer at Programming Puzzles & Code Golf. The question said this:

Given an input string S, print S followed by a non-empty separator in the following way:

  • Step 1: S has a 1/2 chance of being printed, and a 1/2 chance for the program to terminate.

  • Step 2: S has a 2/3 chance of being printed, and a 1/3 chance for the program to terminate.

  • Step 3: S has a 3/4 chance of being printed, and a 1/4 chance for the program to terminate.

  • Step n: S has a n/(n+1) chance of being printed, and a 1/(n+1) chance for the program to terminate.

So I went and wrote this code (ungolfed):

Action<string> g = s =>
{
    var r = new Random();
    for (var i = 2; r.Next(i++) > 0;)
        Console.Write(s + " ");
};

This code works fine, but then someone said that I could save a few bytes creating the r variable inline, like this:

Action<string> g = s =>
{
    for (var i = 2; new Random().Next(i++) > 0;)
        Console.Write(s + " ");
};

I tried but when I executed the code, it always went in one of two possibilities:

  • Either the program halted before printing anything (the first call to Next() returns 0), or
  • The program never stops (the calls to Next() never return 0).

When I reverted the code to my original proposal, the program stopped more randomly as expected by the OP.

I know that the new Random() constructor depends on time, but how much? If I add a Sleep() call, the code behaviour starts to seem really random (but not much, the strings returned are still longer than the ones returned by the initial code):

Action<string> g = s =>
{
    for (var i = 2; new Random().Next(i++) > 0; Thread.Sleep(1))
        Console.Write(s + " ");
};

If I increment the sleep time to 10 ms, now the code really behaves like the original one.

So why is this? How much does the Random class depends on time? How exactly does the Random class seeds the number generator when calling the empty constructor?


Note: I know that creating a single Random object is the best practice, I just wanted to know a bit more than what the MSDN says:

The default seed value is derived from the system clock and has finite resolution.

What is that "finite resolution" the Random class default constructor uses as seed? How much time should we separate the construction of two Random objects to get different sequences? How much would those two different sequences differ when creating the Random instances too close in time?

解决方案

What is that "finite resolution" the Random class default constructor uses as seed?

It uses Environment.TickCount which has a resolution of one millisecond.

How much time should we separate the construction of two Random objects to get different sequences?

As per the previous section, by at least one millisecond - or manually feed another seed to the constructor each time (or, well, reuse the same generator?)

How much would those two different sequences differ when creating the Random instances too close in time?

Matt Moss did a nice visualization in his Random Headaches from System.Random blog post:

Each row of the bitmap represents five first generated numbers with that seed (without preserving generated order):

As you can see, numbers are being selected from distinct but related sequences. As MSDN on Random says, "The chosen numbers... are sufficiently random for practical purposes."

这篇关于new Random() 在多大程度上取决于时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆