Same random numbers from instantiated class

2019-05-31 14:47发布

问题:

I'm learning C# and created a class within my program that holds a random number generator:

class RandomNumberGenerator
{
    Random RNG = new Random();
    // A bunch of methods that use random numbers are in here
}

Inside this class are a few methods that use the RNG. Data gets sent here from other parts of the program, gets processed, then gets returned. One of the methods does the following:

// Method works something like this
int Value1 = RNG.Next(x, y);
int Value2 = RNG.Next(x, y);
int Value3 = RNG.Next(x, y);

The x, y values are to be sent here from another class. So, I have to create an instance of the RandomNumberGenerator within that class so I can call its methods and pass the x and y values to it.

class DoStuff
{
    RandomNumberGenerator Randomizer = new RandomNumberGenerator
    // Here I call a bunch of Randomizer methods that give me values I need
}

The problem in the above method is that I get the same numbers every time for all three values. I'm not sure if it's because they're so close together and Randomizer's seed value hasn't had time to change or if I'm doing something wrong when I create a new instance of the RandomNumberGenerator class.

I've gone through a bunch of answers on here already and typically problems like this are due to people creating many new Random objects when they run methods (thus setting the seed for all of them to the same value), but the only new Random object I create is within the RandomNumberGenerator class. I then instantiate that once within the other class so I can pass it data and use its methods.

Why is this happening and how would I fix this?

回答1:

In general, you should have one static instance of Random, and use that single instance to get all random numbers for your application. Make sure to lock if you are going to use it from multiple threads.



回答2:

I assume that is creating instances of DoStuff in a loop.

When invoked too quickly, multiple random instances will produce identical seeds which causes same numbers.

Declare it once outside the for loop or pass it to the method.

    Random r = new Random();
    for (int i = 0; i < count; i++)
    {
        // use the same random instance
    }

From MSDN:

The random number generation starts from a seed value. If the same seed is used repeatedly, the same series of numbers is generated. One way to produce different sequences is to make the seed value time-dependent, thereby producing a different series with each new instance of Random. By default, the parameterless constructor of the Random class uses the system clock to generate its seed value, while its parameterized constructor can take an Int32 value based on the number of ticks in the current time. However, because the clock has finite resolution, using the parameterless constructor to create different Random objects in close succession creates random number generators that produce identical sequences of random numbers.



标签: c# random