rand() + rand()具有局部作用域

srand() + rand() with local scope

本文关键字:rand 作用域 局部      更新时间:2023-10-16

我有一个函数调用 andrand,像这样:

void foo() {
   int seed = some_operation();
   std::srand(seed);
   int value = std::rand();
   // Do something with random value
}
但是,我不想改变的全局状态。那么得到随机数最简单的方法是什么呢?

要求:

  • 随机数必须是基于种子的确定性
  • c++ 11就可以了
  • foo应该是线程安全的
  • 全局状态不能修改
编辑:

有一个stackoverflow问题询问如何生成随机数。然而,接受的答案显示了如何使用慢的std::random_device生成真正唯一的随机数。我只需要一个使用固定种子的简单生成器。

c++ 11可以

然后使用新的伪随机数库:

#include <random>
int foo() {
    int seed = some_operation();
    std::minstd_rand rand(seed);
    int value = rand();
    // Do something with random value
}

minstd_rand是一个简单的线性同余引擎,类似于std::rand()使用的典型引擎,但是它的状态被封装在一个类中。如果您需要更高质量的伪随机序列,也可以使用其他引擎。如果您没有特殊要求,梅森扭扭机std::mt19937通常是一个不错的选择。

<random>定义了一些您可以使用的PRNG类,它们不使用全局状态。

例如,使用默认的Mersenne Twister, std::mt19937:

#include <iostream>
#include <random>
int main() {
  int seed = 1234;
  std::mt19937 rng(seed);
  std::cout << "Random number: " << rng() << std::endl;
}

一种方法是提供自己的实现,带有自己的种子数据。rand()的手册中提供了这样做的模板。

static unsigned long next = 1;
/* RAND_MAX assumed to be 32767 */
int myrand(void) {
    next = next * 1103515245 + 12345;
    return((unsigned)(next/65536) % 32768);
}
void mysrand(unsigned seed) {
    next = seed;
}