C++ 我应该如何播种一个随机引擎?

C++ 我应该如何播种一个随机引擎?,c++,c++11,random,C++,C++11,Random,我经常看到std::random\u设备被用来为随机引擎播种。在libstdc++中,如果硬件RNG可用,则默认使用IA-32 RDRAND,否则/dev/uradom。libc++可以在arc4random()、/dev/uradom和nacl\u secure\u random之间进行选择。Windows可能使用RtlGenRandom或Crypt API 当然,还有更多的选择: 特定于英特尔: __asm__ __volatile__ ("rdtsc" : "=a"(lo)); PID:

我经常看到
std::random\u设备
被用来为随机引擎播种。在libstdc++中,如果硬件RNG可用,则默认使用IA-32 RDRAND,否则
/dev/uradom
。libc++可以在
arc4random()
/dev/uradom
nacl\u secure\u random
之间进行选择。Windows可能使用
RtlGenRandom
或Crypt API

当然,还有更多的选择:

特定于英特尔:

__asm__ __volatile__ ("rdtsc" : "=a"(lo));
PID:

线程ID:

std::this_thread::get_id()
使用chrono:

std::chrono::high_resolution_clock::now()
                        .time_since_epoch().count();
对于libstdc++来说,这并不总是纳秒分辨率:

#ifdef _GLIBCXX_USE_CLOCK_REALTIME
      timespec tp;
      // -EINVAL, -EFAULT
#ifdef _GLIBCXX_USE_CLOCK_GETTIME_SYSCALL
      syscall(SYS_clock_gettime, CLOCK_REALTIME, &tp);
#else
      clock_gettime(CLOCK_REALTIME, &tp);
#endif
      return time_point(duration(chrono::seconds(tp.tv_sec)
                 + chrono::nanoseconds(tp.tv_nsec)));
#elif defined(_GLIBCXX_USE_GETTIMEOFDAY)
      timeval tv;
      // EINVAL, EFAULT
      gettimeofday(&tv, 0);
      return time_point(duration(chrono::seconds(tv.tv_sec)
                 + chrono::microseconds(tv.tv_usec)));
#else
      std::time_t __sec = std::time(0);
      return system_clock::from_time_t(__sec);
#endif
libc++也有类似的问题:

#ifdef CLOCK_REALTIME
    struct timespec tp;
    if (0 != clock_gettime(CLOCK_REALTIME, &tp))
        __throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed");
    return time_point(seconds(tp.tv_sec) + microseconds(tp.tv_nsec / 1000));
#else  // !CLOCK_REALTIME
    timeval tv;
    gettimeofday(&tv, 0); // :(
    return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
#endif  // CLOCK_REALTIME

其他选项包括编译元数据的散列(
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。如果不是,我建议将列出的所有内容连接到一个大字符串中,然后在该字符串上计算哈希代码。(至少您列出的所有内容都不是多余的,也就是说,同时使用
gettimeofday
std::chrono::high_resolution_clock::now

如果您可以访问
std::random_设备
,我建议您使用它。如果不是,我建议将列出的所有内容连接到一个大字符串中,然后在该字符串上计算哈希代码。(至少您列出的所有内容都不是多余的,即使用
gettimeofday
std::chrono::high_resolution\u clock::now

您应该如何为RNG播种取决于您的目的

您提到的选项不是高熵种子,不适合在随机性质量非常重要的应用程序中使用。例如,为了科学或金融目的的数值实验。或用于加密目的


std::random_device
的目的是提供适合这些应用的跨平台种子源。如果你只是在做一个游戏或别的什么,除非它是一个核心战略游戏,而且你真的很在乎,否则你只要像人们至少已经做了20年的那样使用
srand(time(NULL))
rand
就可以了。

你应该如何播种你的RNG取决于你的目的

您提到的选项不是高熵种子,不适合在随机性质量非常重要的应用程序中使用。例如,为了科学或金融目的的数值实验。或用于加密目的


std::random_device
的目的是提供适合这些应用的跨平台种子源。如果你只是在做一个游戏或别的什么,除非它是一个核心战略游戏,你真的很在乎,否则你只要像人们至少已经做了20年的那样,使用
srand(time(NULL))
rand
,肯定没问题?使用MinGW时要小心,我认为它总是返回0或其他什么。现在可能已经修复。你能告诉我更多为什么需要为RNG设定种子吗?@Severin Pappadeux:也许,出于某种奇怪的原因,他不想每次运行程序时都得到相同的序列?:)@PaulGroke,这与他(或她)想要在多个核之间分割运行的更常见的情况大不相同。不同的问题有不同的解决方案…std::random_设备的问题可能重复?使用MinGW时要小心,我认为它总是返回0或其他什么。现在可能已经修复。你能告诉我更多为什么需要为RNG设定种子吗?@Severin Pappadeux:也许,出于某种奇怪的原因,他不想每次运行程序时都得到相同的序列?:)@PaulGroke,这与他(或她)想要在多个核之间分割运行的更常见的情况大不相同。不同的问题有不同的解决方案…可能重复
#ifdef CLOCK_REALTIME
    struct timespec tp;
    if (0 != clock_gettime(CLOCK_REALTIME, &tp))
        __throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed");
    return time_point(seconds(tp.tv_sec) + microseconds(tp.tv_nsec / 1000));
#else  // !CLOCK_REALTIME
    timeval tv;
    gettimeofday(&tv, 0); // :(
    return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
#endif  // CLOCK_REALTIME