5

可能重复:
有效地生成随机数

我需要random numbers在我的C++应用程序中生成。看了这两篇文章就知道了——

http://www.cprogramming.com/tutorial/random.html

编写 ac 函数,生成一个随机数,或一对随机数,或给定特定范围的三组随机数

- 可以使用生成随机数srand()rand()但在这两种情况下,根据 的当前时间system clock用作seed. 但我在第一篇文章中读到,rand()如果种子相同,将创建相同的随机数。因此,如果两个不同的用户同时运行我的应用程序,那么他们将拥有相同的随机数。这将毫无意义,因为我需要随机数在大多数情况下是唯一的。(我知道如果它们是随机生成的,它们就不能真正 100% 唯一)

所以我的问题是我可以创建一个不基于系统时间的随机种子吗?如果可以,为什么rand()用相同的种子产生相同的数字,有没有办法rand()用相同的种子产生不同的数字,或者还有其他的吗生成随机数的方法?

4

4 回答 4

8

如果不使用特殊的硬件(即使那样,它也值得商榷),就没有计算机生成的真正随机数这样的东西。

话虽如此; 您唯一的问题是:您如何生成种子,以使两个程序不会生成相同的数字。使用当前时间作为种子的一部分是合理的,但正如您所理解的,这还不够,因为两个程序可以同时生成它们的种子......所以您需要根据在程式。可能性包括进程 ID(如果两个程序在同一台计算机上会有所不同),硬件 MAC 地址(如果两个程序在不同的计算机上会有所不同),或计时用户执行某项任务所需的时间(通常只要用户是人,而不是自动化,就会有所不同)。

于 2012-09-30T16:24:00.380 回答
3

根据您的具体要求,您的解决方案可能很简单:

struct timeval;
gettimeofday(&time, NULL);
srand(hash3(time.tv_sec, time.tv_usec, getpid()));

您可以使用任何三个整数散列函数,例如这个:

unsigned int hash3(unsigned int h1, unsigned int h2, unsigned int h3)
{
    return ((h1 * 2654435789U) + h2) * 2654435789U) + h3;
}
于 2012-09-30T16:27:08.183 回答
2

除了其他答案之外,在 Linux(和其他一些 Unix)系统上,您可以从/dev/random/dev/urandom伪设备读取几个字节(至少为您的 PNRG 播种)。另请仔细阅读random(4)/dev/random手册页(其中也解释了和之间的重要区别/dev/urandom

如果为最新的C++2011标准(而不是以前的标准)编码,您可能会对它的<random>标题感兴趣。然后使用最新的GCC编译器(例如 4.7)和libstdc++

于 2012-09-30T16:28:57.203 回答
0

实现真正的随机数生成器是不可能的,但有许多不错的伪随机函数实现可能会对您有所帮助:

  1. Boost.Random: http: //www.boost.org/doc/libs/1_51_0/doc/html/boost_random.html
  2. C++11<random>头文件:http ://www.cplusplus.com/reference/std/random/
  3. <stdlib.h>包含rand()函数的 C头文件: http ://www.cplusplus.com/reference/clibrary/cstdlib/rand/
于 2012-09-30T16:33:56.750 回答