boost :: random :: variate_generator - 构造后更改参数

时间:2016-03-29 15:53:04

标签: c++ boost random

是否可以在构造变量生成器后更改分布的参数? 我们来举例说明这个简单的设置

typedef boost::mt19937 base_gen_type;
typedef boost::uniform_int<int> dist_type;
typedef boost::variate_generator<base_gen_type &, dist_type> var_gen_type;

unsigned seed = 1337;
int a = 0, b = 42;

base_gen_type base_gen(seed);
dist_type dist(a, b);
var_gen_type rng(base_gen, dist);

如果我想更改ab,是否需要新的var_gen_type对象? base_gen的状态当然不受影响,但我想知道是否有一种不太复杂的方式。

使用dist_type &作为模板参数无效。

1 个答案:

答案 0 :(得分:0)

从文档:“请注意,下面描述的所有伪随机数生成器都是CopyConstructible和Assignable。复制或分配生成器将复制其所有内部状态,因此原始和副本将生成相同的随机数序列。 “因此,您可以通过重新设置新值来确保重用“rng”名称。

虽然没有什么可以用来改变增强分布,但是你需要构造新的对象。我认为这是由于分布是不同类型的,这反过来又会改变范围生成器的类型。

但是如果你想改变发行版的范围,你可以通过调用来访问它:

distribution_type& distribution()

根据1.58 source

返回对私有成员的引用

这很有道理,好像你想使用不同类型的分布,持有类型声明也会有所不同。

#include <boost/random.hpp>
#include <iostream>

typedef boost::mt19937 base_gen_type;
typedef boost::uniform_int<int> dist_type;
typedef boost::variate_generator<base_gen_type &, dist_type> var_gen_type;

int main(){
unsigned seed = 1337;
int a = 0, b = 1;

  base_gen_type base_gen(seed);
  dist_type dist(a, b);
  var_gen_type rng(base_gen, dist);
  for(int i = 0; i < 10 ; i++) {
    std::cout << rng() << " " << std::endl; 
  }

  dist_type newdist(0,3);
  rng.distribution() = newdist;

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

}

这会产生:

0 
1 
0 
0 
0 
1 
0 
0 
0 
0 
2 
2 
1 
1 
3 
1 
2 
1 
0 
3 

这就是改变为范围分配的分配的方法。

在更改实际类型方面,它不是由指针存储的,所以使用它的更好方法是使用不同的发行版调用生成器,如下所示:

boost::random::mt19937 rng;         // produces randomness out of thin air
                                    // see pseudo-random number generators
boost::random::uniform_int_distribution<> six(1,6);
                                    // distribution that maps to 1..6
                                    // see random number distributions
int x = six(rng);                   // simulate rolling a die

最后一个例子来自boost随机文档here。 这样,您可以将相同的生成器传递给不同的范围分布。

最后一种方法不是修改整个分布,而只是改变一个参数(如果分布取决于它以前的值可能有用),只需交换这一行:

dist_type newdist(0,3);
rng.distribution() = newdist;

到此:

rng.distribution().param(dist_type::param_type(0,3));

希望它有所帮助。