Adam893
Adam893

Reputation: 143

Improving the quality of random number generation in Qt 5.3

I am currently implementing a random number generator in Qt5.3 as part of genetic algorithm experiments. I have tried several methods but the best seems to be:

  // Seed the random generator with current time
  QTime time = QTime::currentTime();
  qsrand((uint)time.msec());

And then this funtion to generate the random numbers:

int MainWindow::getRandomNo(int low, int high)
{
    return qrand() % ((high + 1) - low) + low;
}

Because of the nature of these experiments, the random nature of these numbers is important. Is there a way to improve the quality of the random number samples? Upon statistical analysis, the Qt random number generator exhibits typical patterns that are found in older systems of random number generation.

The method used above relies on the current time as a seed for the number generator. Is there a way to improve the seed so that the random sequences are less prone to patterns? I would be extremely grateful for any help.

Upvotes: 2

Views: 10830

Answers (3)

H.B
H.B

Reputation: 21

an amendment to dohashi's answer can be to take m as the first prime number greater than or equal to n

Upvotes: 1

Simon Warta
Simon Warta

Reputation: 11408

Use MT.

You can get an implementation here:

I ran into the same problem years ago in a delphi software, and switching to MT sovled my problem. But check the list in the boost docu for further detailed information about the differences between RNG algorithms.

Upvotes: 2

dohashi
dohashi

Reputation: 1841

Adjusting your seed won't really effect the quality of the numbers generated, just the particular order of the numbers generated. You will need to use a better algorithm to generate your random numbers.

In addition, the way you are using the generated numbers is slightly biased. With your getRandomNo function, there will be a slight bias towards smaller numbers. For example if qrand returns a value in the range 0..2^32-1, and you have low=0 and high=2^32-2, then using % as you do, will mean that 0 will be returned (approximately) twice as often as any other number.

An improvement would be to try something like this:

Let n be a positive integer where you want a random integer in the range 0..n-1, let m be the smallest power of 2 greater than or equal to n.

unsigned int myrand( unsigned int n, unsigned int m )
{
    unsigned int i = qrand() % m; /* or (qrand() & (m-1)) */
    while ( i >= n )
    {
        i = qrand() % m;
    }

    return i;
}

This will be slower, but the expected number of iterations is 2. Also, if you are using the same range multiple times, you can pre-compute m.

Upvotes: 1

Related Questions