为什么我的随机数生成器为两个数组播种相同的数字?

时间:2011-02-11 13:27:47

标签: c# .net random

我正在使用一种方法来创建两个带有随机数的新int数组, 但是这两个数组包含完全相同的数字。为什么会这样?

    static void Main(string[] args)
    {
        int[] Foo1= Foo(1000);
        int[] Foo2= Foo(1000);
    }
    static int[] Foo(int length)
    {
        int[] Array = new int[length];
        Random r = new Random();
        for (int i = 0; i < length; i++)
        {          
            Array[i]=r.Next(1, 101);   
        }
        //Thread.Sleep(6);
        return Array;
    }

6 个答案:

答案 0 :(得分:6)

你不是seeding Random但你可能在调用之间使用它足够接近默认种子在两种情况下相同:

  

默认种子值派生自   系统时钟并且有限   解析度。结果,不同   在中创建的随机对象   通过致电来接近接班人   默认构造函数将具有   相同的默认种子值,   因此,将产生相同的集合   随机数。这个问题可以   通过使用单个随机避免   对象生成所有随机数。   你也可以解决它   修改返回的种子值   系统时钟然后明确   为这个新的种子价值提供   随机(Int32)构造函数。更多   信息,请参阅随机(Int32)   构造

答案 1 :(得分:5)

这是因为你的随机数被初始化了两次,时间差太小而没有种子。

试试这个:

static void Main(string[] args)
{
    Random r = new Random();
    int[] Foo1= Foo(1000,r);
    int[] Foo2= Foo(1000,r);
}
static int[] Foo(int length, Random r)
{
    int[] Array = new int[length];

    for (int i = 0; i < length; i++)
    {          
        Array[i]=r.Next(1, 101);   
    }
    //Thread.Sleep(6);
    return Array;
}

答案 2 :(得分:5)

“你正在使用具有相同种子的两个Random实例”的其他答案是正确的。但是,他们曾经使用静态变量来引用Random的实例。如果您尝试从多个线程使用它,这可能会导致问题,因为Random不是线程安全的。

有各种解决方法(例如为每个线程创建一个Random实例,使用静态方法安全地访问它) - 我写了quite a long article on this topic,你可能会发现它很有用。< / p>

答案 3 :(得分:3)

这是因为Random类不是真正的随机数,而是伪随机数。因此,每次在短时间内初始化新的Random实例时,它将再次以相同的数字开头。如果时间跨度越大,你就会有不同的种子,所以它会起作用。我建议在Random中声明Main个实例并将其交给Foo方法,所以它看起来像这样:

static void Main(string[] args)
{
    Random r = new Random();
    int[] Foo1= Foo(1000, r);
    int[] Foo2= Foo(1000, r);
}
static int[] Foo(int length, Random r)
{
    int[] Array = new int[length];
    for (int i = 0; i < length; i++)
    {          
        Array[i]=r.Next(1, 101);   
    }
    //Thread.Sleep(6);
    return Array;
}

编辑:我在Jon Skeet的建议之后修改了上面的代码。现在他提到的问题应该消失了。

答案 4 :(得分:3)

您可以使用全局Random对象,也可以使用像

这样的好种子
  new Random(Guid.NewGuid().GetHashCode());

答案 5 :(得分:1)

因为你使用的是几乎相同的种子。尝试在该方法之外移动Random r = new Random();