System.Random 不是那么随机,为什么会出现这种情况?

Tin*_*ter 1 c#

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

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

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);
}
Run Code Online (Sandbox Code Playgroud)

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

编辑

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

Run*_* FS 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);
}
Run Code Online (Sandbox Code Playgroud)

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

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

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