c使用单个生成器从多个范围提升随机整数

c++ Boost random ints from multiple ranges using single generator

使用boost :: random我试图从不同范围对均匀分布的整数集进行采样,但是要使用相同的底层随机数生成器。对于每个范围,我定义了一个返回随机数的不同函数。
但是,似乎每个函数都返回相同的数字。

说明此方法的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/random.hpp>

struct RandomNumberGenerator {
  boost::mt19937 generator;

  RandomNumberGenerator(long seed) {
    generator.seed(seed);
  }

  boost::function<int()> getRandomFunctionInt(int min, int max) {
    boost::uniform_int<> uni_dist(min, max);
    boost::variate_generator<boost::mt19937&, boost::uniform_int<> > uni(generator, uni_dist);

    boost::function<int()> f;
    f = boost::bind(uni_dist, generator);
    return f;
  }
};

int main (int argc, char* argv[]) {
  RandomNumberGenerator rng(1729);
  boost::function<int()> runif1 = rng.getRandomFunctionInt(0,  1000);
  boost::function<int()> runif2 = rng.getRandomFunctionInt(0, 10000);

  for (int i=0; i<10; ++i) {
    std::cout << runif1() <<"," << runif2() << std::endl;
  }
}

输出为:

1
2
3
4
212, 2121
623, 6226
259, 2590
[...]

有什么方法可以取消功能的相关性?为了使实验具有可重复性,我想使用一个种子。


1
f = boost::bind(uni_dist, generator);

您需要将引用传递给生成器。现在,您正在传递生成器的副本,这意味着每个f对象在其初始状态下都具有生成器的副本。

1
f = boost::bind(uni_dist, boost::ref(generator));

使用Lambdas的其他版本将使歧义更明显(并且更易于检测/解决):

1
f = [uni_dist, this] {return uni_dist(generator);};

此外,c 11引入了<random>标头,该标头提供了所有相同的功能,以及boost的random标头提供的更多功能,因此,实际上没有任何理由再继续使用boost版本。