Rand()返回相同或非常相似的输出值

时间:2013-12-21 08:44:50

标签: c++ random time seed srand

C ++问题,使用Code :: Blocks。 我正在尝试运行此代码来测试伪随机函数

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
    int count = 0;
    while (count < 10){
        srand(time(NULL));
        cout << rand() << ' ';
        cout << (time( NULL )) << " \n";
        count++;
    }
    return 0;
}

此输出为10条相等的线。这不是真正的问题,因为这里的种子是相同的,所以结果应该是相同的。问题是如果我再次运行这个程序,它会产生10个非常相似的行,不仅在time()输出上有很小的变化,而且在rand输出上也是如此。

srand(time(NULL))给出了非常相似的答案,这些答案基本上是相同的返回值,只是稍大一些。

(第一次运行时返回9631,然后是第二次运行时返回9656)。

我的问题是,这是预期的行为吗?如何在第一次运行时获得更多不同的结果,如38,在第二次运行时获得671?

3 个答案:

答案 0 :(得分:2)

这里有很多误解......预计两个time(NULL)次呼叫之间的差异很小。毕竟,时间的移动速度非常快。下一个问题是rand()返回(伪)随机值(质量不同):在这种情况下,随机意味着您可能会重复几次33,只要它不可预测。话虽如此,rand()依赖于实现,很可能你的实现使用类似LCG的东西,它不会产生良好的统一随机值。唯一的解决方法是切换到不同的rng。由于这被标记为C ++,您可能需要查看C ++ 11s随机标题并使用类似mersenne twister实现的内容,这是一个很好的伪随机数生成器,它可以生成质量高,分布均匀的随机数。 / p>

答案 1 :(得分:1)

不同执行之间的差异可能是time变化的微小差异。对于不同的C运行时,rand的结果可能不同,但这是Visual Studio 10中rand的实现。

int __cdecl rand ()
{
    _ptiddata ptd = _getptd();

    return( ((ptd->_holdrand = ptd->_holdrand * 214013L
        + 2531011L) >> 16) & 0x7fff );
}

holdrand存储种子以开始使用。这是linear congruential generator,通常不会产生高质量的随机性。它每次都会丢掉很多状态但没有帮助。

答案 2 :(得分:0)

要使用几乎相同的种子(时间)创建一个随机数,您可以添加一个静态变量,使rand()即使使用相同的参数也会表现不同;或者,您可以在同一时间更改参数。例如:

int t=0;
...
rand(t=(t*7)^time(NULL));