简体   繁体   English

在Qt 5.3中提高随机数生成的质量

[英]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. 我目前正在Qt5.3中实现随机数生成器,作为遗传算法实验的一部分。 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. 经过统计分析,Qt随机数生成器展现出在较早的随机数生成系统中发现的典型模式。

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. 我将非常感谢您的帮助。

Use MT . 使用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. 多年前,我在delphi软件中遇到了同样的问题,而切换到MT解决了我的问题。 But check the list in the boost docu for further detailed information about the differences between RNG algorithms. 但是,请查看boost文档中的列表,以获取有关RNG算法之间差异的更多详细信息。

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. 使用您的getRandomNo函数,对较小的数字会有轻微的偏差。 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. 例如,如果qrand返回范围为0..2^32-1的值,并且您具有low=0high=2^32-2qrand %进行操作,将意味着将返回0 (大约) )的频率是其他数字的两倍。

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 . 假设n是一个正整数,而您想要一个0..n-1范围内的随机整数,则m是大于或等于n的2的最小幂。

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 . 这会比较慢,但是预期的迭代次数是2。此外,如果多次使用相同的范围,则可以预先计算m

dohashi答案的修正可以是将m作为大于或等于n的第一个素数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM