【问题标题】:boost::random::variate_generator - Change parameters after constructionboost::random::variate_generator - 构造后更改参数
【发布时间】:2016-03-29 15:53:04
【问题描述】:

是否可以在变量生成器构建后更改分布的参数? 让我们以这个简单的设置为例

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 &amp; 作为模板参数不起作用。

【问题讨论】:

    标签: c++ boost random


    【解决方案1】:

    来自文档:“请注意,下面描述的所有伪随机数生成器都是 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));
    

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 2017-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多