2013-12-21 29 views
2

这里的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(时间(NULL))是给这基本上是相同的返回值非常相似的答案,只有一点点大。

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

我的问题是,是预期的行为?我怎么能得到更多不同的结果,如第一次运行38次,第二次运行671次?

+0

你能更精确吗?你期望看到什么?你看到了什么?这如何不能达到你的期望? –

回答

0

为了使随机数与一个几乎相同的种子(时间),你可以添加一个静态变量,使rand()行为即使有相同的参数不同;或者,当你获得相同的时间时,你可以改变参数。例如:

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

这实际上是一个很好的解决方案!我这样做了,我可以使用同一时间获得100种不同的解决方案(通过运行此程序一次,同时计数达到100)。再次运行它似乎解决方案的可预测性也非常非常低。我唯一需要补充的是我需要改变的函数调用是srand,而不是rand。但我明白你的意思。非常感谢! –

2

这里很多的误解......这接近两个彼此time(NULL)调用之间的差别很小,预计。毕竟,时间过得很快。接下来的问题是rand()返回一个(伪)随机值(不同质量):在这种情况下,随机意味着您可以重复几次,只要它不可预测。这就是说,rand()是依赖于实现的,很可能你的实现使用了类似于LCG的东西,它不会生成好的统一的随机值。唯一的解决方法是切换到不同的rng。由于它被标记为C++,因此您可能需要查看C++ 11s随机头并使用像mersenne twister实现这样的东西,这是一个很好的伪随机数生成器,可生成高质量,均匀分布的随机数。

+0

我知道这一切。我只是说,一旦我知道我第一次运行我的程序的价值,我可以期待如果我关闭它并再次运行它,我会得到什么样的价值。我甚至可以计算出这个数字需要多长时间才能达到某个特定点,然后我可以始终预测我将从中得到的数量。这不是随意给我的。甚至没有任何伪随机。如果我只是打印“时间(空)”,结果将是相同的:总是以一定的速度增长的数字。 –

1

变化执行之间的差异想必会变化的在time差小。的rand结果可以为不同的C运行时不同,但这里是rand从Visual Studio 10

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

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

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

+0

所以基本上,这意味着rand的工作方式实际上是一个线性和可预测的功能?那么,我猜想让它看起来像返回一个随机值的唯一方法是,如果我限制了我可以从中获得的最大值。就像使用rand(时间(0))%10或%一个数字一样。我试图得到更加相似和可预测结果的结果会越大。 –