【问题标题】:Improving the quality of random number generation in Qt 5.3提高 Qt 5.3 中随机数生成的质量
【发布时间】:2014-10-03 16:51:10
【问题描述】:

我目前正在 Qt5.3 中实现一个随机数生成器,作为遗传算法实验的一部分。我尝试了几种方法,但最好的方法似乎是:

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

然后这个函数来生成随机数:

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

由于这些实验的性质,这些数字的随机性很重要。有没有办法提高随机数样本的质量?经过统计分析,Qt 随机数生成器显示出在旧的随机数生成系统中发现的典型模式。

上面使用的方法依赖于当前时间作为数字生成器的种子。有没有办法改进种子,使随机序列不太容易出现模式?如果有任何帮助,我将不胜感激。

【问题讨论】:

  • 有什么理由不使用<random> 吗?它更加强大。
  • 它似乎也遇到了同样的模式问题——在足够大的样本量下几乎可以预测。
  • 每个 PRNG 都可以通过“足够大”的样本量进行预测。但是对于好的算法来说,“足够大”是不可能的。你有没有看过可用的? cplusplus.com/reference/random
  • 这个特殊的应用程序是对进化过程的模拟,因此输入越随机,性能就会越好。您提到的随机数生成器非常棒-但这就是问题所在,它们太好了。生成的随机序列都分布得太均匀,没有任何用处。所需要的是能够生成真正随机序列的系统。唯一接近这一点的是硬件随机数生成器。到目前为止,我发现的最好的是我的问题中的 Qt,使用时钟作为种子。
  • 没有“太好”的RNG。 Mersenne Twister 将为您提供具有(几乎)相同概率的任何数字序列。甚至是 0 - 0 - 0 - 0 - 0 之类的序列

标签: c++ qt random seeding qt5.3


【解决方案1】:

使用MT

你可以在这里得到一个实现:

几年前我在一个 delphi 软件中遇到了同样的问题,然后切换到 MT 解决了我的问题。但请查看 boost 文档中的列表,了解有关 RNG 算法之间差异的更多详细信息。

【讨论】:

  • 你错过了最明显的地方:<random>。您不需要额外的库。
  • 找到了解问题的人让我如释重负!感谢 MT 的提示,它带来了显着的不同。
  • @Adam893:既然你问了,每个人都把你指向了 标题。瞧,有一个 MT 实施。但那时候,你说它“太好了”……?
【解决方案2】:

调整种子不会真正影响生成数字的质量,只会影响生成数字的特定顺序。您需要使用更好的算法来生成随机数。

此外,您使用生成数字的方式略有偏差。使用您的 getRandomNo 函数,会稍微偏向较小的数字。例如,如果qrand 返回0..2^32-1 范围内的值,并且您有low=0high=2^32-2,那么使用% 将意味着0 将返回(大约)两倍通常与任何其他数字一样。

一个改进是尝试这样的事情:

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

这会比较慢,但预期的迭代次数是 2。另外,如果您多次使用相同的范围,您可以预先计算 m

【讨论】:

    【解决方案3】:

    dohashi的答案的修改可以是把m作为大于等于n的第一个素数

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-30
      • 1970-01-01
      相关资源
      最近更新 更多