System.Random不是那么随机,为什么会这样?

时间:2012-10-15 18:48:28

标签: c#

  

可能重复:
  Random number generator only generating one random number

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

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 个答案:

答案 0 :(得分:4)

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

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

如果您将代码更改为以下内容,则会有更多随机行为

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可以是使用哪个函数的属性),列表中列表的前几个数字几乎相同,但最终会有很大差异。

答案 1 :(得分:1)

使用第一个随机数生成第二个。不再使它成为“随机”。正如建议尝试的那样。

同样建议不需要在循环内生成随机对象。

    Random globalRand = new Random();

    for (int i = 0; i < 100; i++)
    {
        int value = globalRand.Next(1, 511);
        Console.WriteLine(value);
    }

答案 2 :(得分:0)

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

答案 3 :(得分:0)

我相信Random()是基于时间的,所以如果您的流程运行得非常快,如果您继续在循环中创建Random()的新实例,则会得到相同的答案。尝试在循环外部创建Random(),然后使用.Next()获得如下答案:

Random rand = new Random(); 

for (int i = 0; i < 100; i++) 
{ 
    int value = rand.Next(); 
    Console.WriteLine(value); 
}