1

可能重复:
随机数生成器仅生成一个随机数

我已将在更大系统中观察到的行为提炼成以下代码序列:

for (int i = 0; i < 100; i++)
{
    Random globalRand = new Random(0x3039 + i);

    globalRand.Next();
    globalRand.Next();
    int newSeed = globalRand.Next();

    Random rand = new Random(newSeed);
    int value = rand.Next(1, 511);
    Console.WriteLine(value);
}

从面向 .NET 4.5 的 Visual Studio 2012 运行此程序将输出 316 或 315。将其扩展超过 100 次迭代,您会看到该值缓慢递减(314、313...),但它仍然不是我想象的那样任何人都会考虑“随机”。

编辑

我知道 StackOverflow 上已经有几个问题询问为什么它们的随机数不是随机的。但是,这些问题存在以下问题:a)没有将种子(或相同的种子)传递给它们的 Random 对象实例,或者 b)做类似的事情NextInt(0, 1)并且没有意识到第二个参数是排他性的界限。对于这个问题,这些问题都不是真的。

4

4 回答 4

5

它是一个伪随机生成器,它基本上创建了一个长(无限)的数字列表。该列表是确定性的,但在大多数实际场景中,顺序可以被视为随机的。然而,顺序是由种子决定的。

您可以实现的最随机的行为(没有花哨的裤子技巧,很难一直正确)是一遍又一遍地重用同一个对象。

如果您将代码更改为以下代码,您的行为会更加随机

Random globalRand = new Random();

for (int i = 0; i < 100; i++)
{
    globalRand.Next();
    globalRand.Next();
    int newSeed = globalRand.Next();

    Random rand = new Random(newSeed);
    int value = rand.Next(1, 511);
    Console.WriteLine(value);
}

原因是伪随机生成器背后的数学基本上只是创建了一个无限的数字列表。

这些数字的分布几乎是随机的,但它们出现的顺序却不是。计算机是确定性的,因此无法产生真正的随机数(没有帮助),因此为了规避这个数学天才已经产生了能够产生这些数字列表的函数,这些函数对它们有很大的随机性,但种子决定了顺序。

给定相同的种子,函数总是产生相同的顺序。给定靠近每个订单的两个种子(其中 close 可以是使用哪个函数的属性),列表中的前几个数字几乎相同,但最终会非常不同。

于 2012-10-15T18:51:05.613 回答
1

使用第一个随机数生成第二个。不再让它变得“随机”。按照建议试试这个。

同样如建议的那样,无需在循环内生成随机对象。

    Random globalRand = new Random();

    for (int i = 0; i < 100; i++)
    {
        int value = globalRand.Next(1, 511);
        Console.WriteLine(value);
    }
于 2012-10-15T18:52:29.183 回答
0

如果没有参数 Random c'tor 将当前日期和时间作为种子 - 您通常可以在内部计时器计算出当前日期和时间已更改之前执行大量代码。因此,您重复使用相同的种子 - 并重复获得相同的结果。来源:http ://csharpindepth.com/Articles/Chapter12/Random.aspx

于 2012-10-15T18:58:07.713 回答
0

我相信这Random()是基于时间的,因此如果您的流程运行得非常快,如果您继续Random()在循环中创建新实例,您将得到相同的答案。尝试创建Random()循环的外部并使用.Next()来获得您的答案,例如:

Random rand = new Random(); 

for (int i = 0; i < 100; i++) 
{ 
    int value = rand.Next(); 
    Console.WriteLine(value); 
} 
于 2012-10-15T18:58:41.127 回答