开发者

Why is my Random number generator seeding both arrays with the same numbers? [duplicate]

This question already has answers here: Random number generator only generating one random number (15 answers) Closed 5 years ago.

I'm using a method to create two new int arrays with random numbers, but the two array contains exactly the same numbers. Why is this happening?

    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;
    }


You're not seeding Random but you're likely using it close enough between calls that the default seed is the same in both cases :

The default seed value is derived from the system clock and has finite resolution. As a result, different Random objects that are created in close succession by a call to the default constructor will have identical default seed values and, therefore, will produce identical sets of random numbers. This problem can be avoided by using a single Random object to generate all random numbers. You can also work around it by modifying the seed value returned by the system clock and then explicitly providing this new seed value to the Random(Int32) constructor. For more information, see the Random(Int32) constructor.


it's because your random is initialized twice, with a too small time difference to have a different seed.

try this :

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;
}


The other answers around "you're using two instances of Random with the same seed" are correct. However, they used to use a static variable to refer to an instance of Random. That could cause problems if you try to use it from multiple threads, because Random isn't thread-safe.

There are various workarounds for this (such as creating one instance of Random per thread, with a static method to access it safely) - I've written quite a long article on this topic which you may find useful.


you can use global Random object or you can use a good seed like

  new Random(Guid.NewGuid().GetHashCode());


That is because of the Random class which are not really random numbers, but rather pseudo randoms. So each time a new Random instance is initialized in a short timespan, it begins with the same number again. If the timespan is bigger, you will have a different seed, so it would work. I would suggest to declare the Random instance in Main and hand it over to the Foo method, so it would look like this:

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;
}

Edit: I modified the code above after Jon Skeet's advice. Now the problem mentioned by him should be gone.


Because you are using almost the same seed. Try moving Random r = new Random(); outside of that method.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜