使用boost生成正常随机数的问题 [英] Questions with using boost for generating normal random numbers

查看:102
本文介绍了使用boost生成正常随机数的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我看到

I was hoping to learning how to generate numbers from normal distribution in C++ when I saw This Post. It gives a very good example, but still I am not sure what the & in boost::variate_generator<boost::mt19937&, boost::normal_distribution<> > var_nor(rng, nd); means. What effect will it produce if I did not include this & here?

此外,在阅读

Also, when reading the tutorial on Boost's official website, I found that after generating a distribution object with boost::random::uniform_int_distribution<> dist(1, 6), they were able to directly generate random numbers with it by calling dist(gen)(gen here is the random engine), without invoking the "variate_generator" object. Of course, this is for generating uniform random numbers, but I am curious if I can do the same with normal distribution, as an alternative way to calling "variate_generator"?

推荐答案

简短的背景信息

一种生成具有特定分布的随机数的方法是,例如,从间隔[0,1)生成均匀分布的随机数,然后对这些数字进行一些数学运算,以将它们整形为所需的分布.因此,您有两个对象:一个用于生成[0,1)中的随机数的生成器,另一个是用于分布的对象取均匀分布的随机数,并以所需的(例如正态)分布散布随机数.

Short background information

One approach to generate random numbers with a specific distribution, is to generate uniformly distributed random numbers from the interval [0, 1), for example, and then apply some maths on these numbers to shape them into the desired distribution. So you have two objects: one generator for random numbers from [0, 1) and one distribution object, which takes uniformly distributed random numbers and spits out random numbers in the desired (e.g. the normal) distribution.

代码中的 var_nor 对象将生成器 rnd 与正态分布 nd 耦合.您必须通过引用传递生成器,引用是模板参数中的& .这真的很重要,因为随机数生成器具有内部状态,可以根据该状态计算下一个(伪)随机数.如果不通过引用传递生成器,则将创建它的副本,这可能会导致代码,该代码始终创建相同的随机数.参见此博客文章.

The var_nor object in your code couples the generator rnd with the normal distribution nd. You have to pass your generator via reference, which is the & in the template argument. This is really essential, because the random number generator has an internal state from which it computes the next (pseudo-)random number. If you would not pass the generator via reference, you would create a copy of it and this might lead to code, which always creates the same random number. See this blog post as an example.

到此为止,为什么不直接在生成器中使用发行版.如果您尝试以下代码

Now to the part, why not to use the distribution directly with the generator. If you try the following code

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

int main()
{
    boost::mt19937 generator;    
    boost::normal_distribution<> distribution(0.0, 1.0);

    // WARNING: THIS DOES NOT WORK AS MIGHT BE EXPECTED!!
    for (int i = 0; i < 100; ++i)
        std::cout << distribution(generator) << std::endl;
    return 0;
}

您将看到,它仅输出 NaN (我已经使用Boost 1.46对其进行了测试).原因是Mersenne扭曲器返回一个均匀分布的整数随机数.但是,大多数(可能甚至是所有)连续分布都需要从[0,1)范围内的浮点随机数.Boost文档中给出的示例有效,因为 uniform_int_distribution 是离散分布,因此可以处理整数RNG.

you will see, that it outputs NaNs only (I've tested it with Boost 1.46). The reason is that the Mersenne twister returns a uniformly distributed integer random number. However, most (probably even all) continuous distributions require floating point random numbers from the range [0, 1). The example given in the Boost documentation works because uniform_int_distribution is a discrete distribution and thus can deal with integer RNGs.

注意:我尚未尝试使用更新版本的Boost进行编码.当然,如果将离散RNG与连续分发一起使用,则编译器抛出错误会很好.

Note: I have not tried the code with a newer version of Boost. Of course, it would be nice if the compiler threw an error if a discrete RNG is used together with a continuous distributuon.

这篇关于使用boost生成正常随机数的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆