srand(time(NULL))生成类似的结果

时间:2011-07-12 17:18:31

标签: c++ visual-studio visual-studio-2010 random

我不明白为什么srand()会在运行之间生成如此相似的随机数

我正在尝试运行以下代码

srand ( time(NULL) );
int x = rand();
cout << x << endl;

然而,不是一个正确的随机数,我总是得到几乎相同的数字,随着时间的推移,这个数字正在缓慢增长。所以我得到的数字如:11669,11685,11701,11714,11731。

我做错了什么?

我正在使用Visual Studio 2010 SP1。

好的,srand()真的那么简单吗?我的意思是如何将其称为随机函数?

srand(1) => rand() = 41
srand(2) => rand() = 45
srand(3) => rand() = 48
srand(4) => rand() = 51
....

8 个答案:

答案 0 :(得分:9)

首先,srand()不是随机函数;它设定了起点 一个伪随机序列。有点令人惊讶的是,你的 rand()的实现似乎正在返回一个基于的值 以前的状态,而不是新计算的状态,所以第一个 调用srand()后的值很大程度上取决于传递给的值 srand()。如果你要写:

srand( time( NULL ) );
rand();
std::cout << rand() << std::endl;

,我相信你会看到更多的不同。

FWIW:我在Windows和Linux上都试过以下内容:

int
main()
{
    srand( time( NULL ) );
    int r1 = rand();
    std::cout << r1 << ' ' << rand() << std::endl;
    return 0;
}

每隔一秒钟调用10次,我得到了:

16391 14979
16394 25727
16397 3708
16404 25205
16407 3185
16410 13933
16417 2662
16420 13411
16427 2139

在Windows下使用VC ++ - 你会注意到它的非常低的方差 先致电rand() - 和

1256800221 286343522
955907524 101665620
1731118607 991002476
1428701871 807009391
44395298 1688573463
817243457 1506183315
507034261 1310184381
1278902902 54648487
2049484769 942368151
1749966544 1833343137

在Windows下使用g ++;在这种情况下,即使读取的第一个值也是如此 相对随意。

如果你需要一个好的随机发生器,你可能不得不使用一个 来自Boost;标准没有说明应该是什么算法 使用,实施的质量差异很大。

答案 1 :(得分:7)

确保你正在做

srand ( time(NULL) );
while(condition) {
    int x = rand();
    cout << x << endl;
}

而不是

while(condition) {
    srand ( time(NULL) );
    int x = rand();
    cout << x << endl;
}

每次迭代都会更改种子的第一种方式。第二种方法是在每次迭代时对非常相似的种子执行随机函数(因为时间变化不大)。

答案 2 :(得分:3)

如果您尝试连续快速运行程序并且每次都获得不同的随机数,则使用当前时间初始化是错误的方法。你需要的是熵的来源; this question可能会让你开始。用time(NULL)替换QueryPerformanceCounter()可能是一个好的开始,因为它更新得更快,但它仍然有些可预测 - 我不知道这对你是否重要。

答案 3 :(得分:3)

由于您拥有Visual Studio 2010,因此您可以使用现代C ++中的可移植random device interface而不是time()来播种srand():

#include <iostream>
#include <random>
#include <cstdlib>
int main()
{
    std::random_device rd;
    std::srand(rd());
    std::cout << std::rand() << '\n';
}

现在重复运行程序仍会产生不同的值。相同的代码适用于Linux或任何其他现代编译器上的GNU g ++。

答案 4 :(得分:1)

好的,Mark Ransom的所有学分都用于解释实际发生的事情。我没有在他的链接问题中找到源代码,所以我用Google搜索并找到了这个,在Windows上完美运行的是什么。所以对于Windows上的srand,这里是生成更好的srand()种子的源代码。

#include <windows.h>

int main()
{
  LARGE_INTEGER cicles;

  QueryPerformanceCounter(&cicles);
  srand (cicles.QuadPart);

  return 0;
}

答案 5 :(得分:1)

我遇到了同样的问题。几十秒后,种子太相似了。因为我以这种方式得到我的数字:

int FlRandomInt(int LowerLimit, int UpperLimit)
{
 int Result;
 Result = rand();
 Result=LowerLimit+Result*(UpperLimit-LowerLimit)/RAND_MAX;

 return Result;
}

我知道这不是整数的最佳方法,但我使用相同的程序生成随机浮点数和双精度数,因此最好验证它们是否有明显不同,而不是仅仅是最后一个小数。

无论如何只想发布一个适合我的解决方案。它只是将时间种子乘以100:

srand(( unsigned )time( 0 ) * 100 );

希望它有所帮助,即使我确定有更优雅的方法解决问题。

答案 6 :(得分:0)

从@James Kanze的测试来看,它似乎是VC ++的C运行时的特性(尽管我确信其他库也以同样的方式受到影响)。该库也有minimum allowable RAND_MAX,但这是另一个问题。

初始值的低方差的解决方案只是丢弃它:

void seed_rand( unsigned int seed )
{
    srand( seed ) ;
    (void)rand() ;
}

int main()
{
    seed_rand( time( NULL ) );
    int r1 = rand();
    std::cout << r1 << ' ' << rand() << std::endl;
    return 0;
}

答案 7 :(得分:0)

#include"stdio.h" //rmv coding for randam number access using c++

 #include"conio.h"

 #include"time.h"

void main()

{

time_t t;

int i;

srand(time(null));

for(i=1;i<=10;i++)

cout<<(unsigned)rand()%100-90<<"\t";

for(i=1;i<=10;i++)

cout<<(char)rand()%100-90<<"\t";


getch();

}