2010-04-04 144 views
4

好的,这是一个非常奇怪的结果。不同的rand()序列在表达式中产生相同的结果

我有一个MPI程序,其中每个进程必须在固定范围内生成随机数(范围从文件中读取)。会发生什么情况是即使我为每个进程使用不同的值,并且每个进程中生成的数字都不相同,但生成随机数的表达式仍然会在它们之间产生相同的序列。

这里的所有相关的代码:

// 'rank' will be unique for each process 
int rank; 
MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
// seed the RNG with a different value for each process 
srand(time(NULL) + rank); 
// print some random numbers to see if we get a unique sequence in each process 
// 'log' is a uniquely named file, each process has its own 
log << rand() << " " << rand() << " " << rand() << std::endl; 

// do boring deterministic stuff 

while (true) 
{ 
    // waitTimeMin and waitTimeMax are integers, Max is always greater than Min 
    waitSecs = waitTimeMin + rand() % (waitTimeMax - waitTimeMin); 
    log << "waiting " << waitSecs << " seconds" << std::endl; 
    sleep(waitSecs); 
    // do more boring deterministic stuff 
} 

这里的每个过程的输出,用3个过程在范围[1,9]产生的数字。

过程1:

15190 28284 3149 
waiting 6 seconds 
waiting 8 seconds 
waiting 9 seconds 
waiting 4 seconds 

过程2:

286 6264 3153 
waiting 6 seconds 
waiting 8 seconds 
waiting 9 seconds 
waiting 4 seconds 

过程3:

18151 17013 3156 
waiting 6 seconds 
waiting 8 seconds 
waiting 9 seconds 
waiting 4 seconds 

因此,尽管rand()清楚地生成不同的数字,表达式来计算waitSecs仍评估为所有进程的序列相同。更奇怪的是:如果我再次运行带有相同参数的程序,只有前3个随机数字会改变,其余的“随机”序列在每次运行中将完全相同!更改数字范围显然会产生与此不同的结果,但执行过程中的进程之间的相同参数始终产生相同的序列:除前3个数字外。

这到底是怎么回事?


编辑:所以只是为了看看它的简单随机生成和/或低的范围内,我取代了随机生成这一行:

waitSecs = waitTimeMin + (int)((double)rand()/((double)RAND_MAX + 1) * (waitTimeMax - waitTimeMin)); 

而且在范围内开始产生数[1,99]。这里的结果:

过程1:

7833 3798 10977 
waiting 1 seconds 
waiting 20 seconds 
waiting 58 seconds 
waiting 35 seconds 
waiting 82 seconds 
waiting 18 seconds 

过程2:

25697 14547 10980 
waiting 1 seconds 
waiting 20 seconds 
waiting 58 seconds 
waiting 35 seconds 
waiting 82 seconds 
waiting 18 seconds 

过程3:

10794 25295 10984 
waiting 1 seconds 
waiting 20 seconds 
waiting 58 seconds 
waiting 35 seconds 
waiting 82 seconds 
waiting 18 seconds 

同样的事情。这仍然只是rand()真的很糟糕?

EDIT2:1生成号码10000

+0

检查是否真的是rand()问题: log <<“min”<< waitTimeMin <<“max”<< waitTimeMax << endl; – 2010-04-04 17:43:21

+0

在每种情况下打印您正在播种srand()的值。 – 2010-04-04 18:15:12

+0

做了那个Neil:过程1为X,过程2为X + 1,过程3为X + 2等。 – suszterpatt 2010-04-04 18:22:21

回答

1

好吧,显然我被推迟了。在初始化RNG之后,我产生了一个新的线程并在那里生成了随机数,而不需要初始化。在新线程中调用srand()可解决问题。所以是的,这里的教训是srand()rand()每个线程工作,而不是每个进程。我还需要在我的问题中发布更多关于我的程序的信息。

Ouch。

对不起浪费大家的时间。

+0

如果你正在使用rand与多线程应用程序,你可能也想看看线程安全版本rand_r,它应该是POSIX指定的可重入的,其中rand不是必须的(但可能取决于实现)。 – 2010-04-04 18:49:33

+0

我认为你可以'接受'自己的答案作为正确答案。这会将它泡到最高层,并防止任何人读这条线来追踪红鲱鱼。 – brainjam 2010-04-04 18:49:52

+0

它不会让我接受2天的答案,必须是一个新功能。另外,我实际上使用Qt的'qrand()',它声称是'rand()'的线程安全版本。 – suszterpatt 2010-04-04 18:52:04

1

当同样的事情,尝试使用一个随机数发生器从TR1像std::tr1::mt19937。通常使用低质量的随机数生成器来实现功能rand()

编辑:低质量可能意味着,例如,即使在[0,100]^2中生成2D点(x,y)也会导致点不均匀分布在正方形中。你可能会认为它不应该表现得那么糟糕,但是你会对它的实际表现有多么的惊讶(这在大多数语言中都是可悲的)。

编辑2:方法range*(rand()/RAND_MAX)不是一个好的。它具有双精度问题,甚至不会产生结果。

请尝试以下,看看你的程序仍然给你,你是感到吃惊的结果:

std::tr1::mt19937 engine(thread_seed); 
std::tr1::uniform_int<> unigen(waitTimeMin, waitTimeMax); 
std::tr1::variate_generator<std::tr1::mt19937, 
          std::tr1::uniform_int<> >gen(engine, unigen); 
waitSec = gen(); 

EDIT3: http://dilbert.com/dyn/str_strip/000000000/00000000/0000000/000000/00000/2000/300/2318/2318.strip.gif

+0

正如你所看到的,前三个数字的%9似乎是相等的:只是rand()的质量太差,以至于你的序列高度相关。 – baol 2010-04-04 17:38:15

+0

我不需要高质量的随机数字,当然'rand()'预计会比这更好。我可能会尝试其他方法,但我仍然想知道是什么导致了这种现象。 – suszterpatt 2010-04-04 17:39:33

+1

也许,但低质量的随机数字不是随机的:)。请注意,高质量的随机数发生器也可能非常快。 – baol 2010-04-04 17:44:17

4

在你的代码只使用低3位,如果产生随机数(除以8的余数)。您的实验显示,生成的数字序列中最低3位的序列每次都是相同的。这是完全可能的。实际上,这是一个众所周知的问题,通常用于实现rand()的简单伪随机数生成器。

如果您想使用rand()(而不是更复杂的自定义生成器),最好使用高位而不是低位。即请勿使用%运营商来减少rand()的范围。在这里看看更好的方法:http://c-faq.com/lib/randrange.html

+0

我使用更大的范围和更好的方法从该网站进行测试,结果相同(请参阅问题中的编辑)。 – suszterpatt 2010-04-04 18:02:27

1

计算(rand() % n)通常是一个坏主意 - 你会得到比随机的结果。相反,如果RAND_MAXrand()的输出范围,请尝试将rand()除以(RAND_MAX/(waitTimeMax - waitTimeMin))。您正在使用的rand()可能是linear congruential generator。如果你遵循后面的链接,你会发现更多关于它是如何工作的信息,以及为什么低位比较高位“不那么随机”的解释。

相关问题