在C++中获取均匀分布的随机整数的标准方法是什么?



是否有用于获取某个指定范围内均匀分布伪随机整数的函数?我可以使用 rand 编写自己的函数,但这似乎是一种足够普遍的情况,以至于 STL 中可能有一些东西。

Boost 提供了许多用于随机数生成的工具。对于均匀分布,你有这个:

http://www.boost.org/doc/libs/1_49_0/doc/html/boost/random/uniform_real_distribution.html

编辑:更新以包括新的C++11实现。对于整数的情况,这里有参考:

http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution

一个简单的例子是:

#include <random>
#include <iostream>
int main()
{
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<> dis(1, 6);
    for(int n=0; n<10; ++n)
        std::cout << dis(gen) << ' ';
    std::cout << 'n';
}

要在C++中生成伪随机数,一个非常好的选择是使用 Mersenne twister 伪随机数生成器引擎:从 <random> 标头 std::mt19937

我们可以把这个引擎想象成一个黑匣子,吐出高质量的随机位

然后,这些随机位可以使用分布

在一些整数输出中整;特别是,为了获得均匀分布的伪随机数,可以使用std::uniform_int_distribution

请注意,引擎对象必须使用 seed.
初始化 std::random_device可用于此目的。

因此,此过程可以概括为三个逻辑步骤:

  1. 创建一个std::random_device实例,以获得梅森费尔托斯特引擎的非确定性种子
  2. 创建std::mt19937引擎的实例,以获得高质量的伪随机位。
  3. 使用 std::uniform_int_distribution将这些随机位塑造均匀分布的整数

可编译C++代码如下:

#include <iostream>     // for console output
#include <random>       // for pseudo-random number generators and distributions
int main()
{
    // Use random_device to generate a seed for Mersenne twister engine.
    std::random_device rd;    
    // Use Mersenne twister engine to generate pseudo-random numbers.
    std::mt19937 engine(rd());
    
    // "Filter" MT engine's output to generate pseudo-random integer values,
    // **uniformly distributed** on the closed interval [0, 99].  
    // (Note that the range is [inclusive, inclusive].)
    std::uniform_int_distribution<int> dist(0, 99);
    // Generate and print 10 pseudo-random integers
    for (int i = 0; i < 10; ++i)
    {
        std::cout << dist(engine) << ' ';
    }
    std::cout << std::endl;
}
<小时 />

有关在C++中生成伪随机数的更多详细信息(包括rand()不好的原因(,请观看Stephan T. Lavavej的视频(来自Go Native 2013(:

rand()被认为是有害的

要使用std::generate_nboost生成一个或指定数量的随机变量,这些随机变量在整数域上均匀分布:

#include <iostream>
#include <algorithm>
#include <boost/random.hpp>
/*
 * 
 */
int main(int argc, char** argv) {
    boost::mt19937 rand_generator(std::time(NULL));
    boost::random::uniform_int_distribution<> int_distribution(0, 100);
    //Need to pass generator
    std::cout << int_distribution(rand_generator) << std::endl;
    //Associate generator with distribution
    boost::random::variate_generator<boost::mt19937&,
            boost::random::uniform_int_distribution<>
            > int_variate_generator(rand_generator, int_distribution);
    //No longer need to pass generator
    std::cout << int_variate_generator() << std::endl;
    std::generate_n( std::ostream_iterator<int>(std::cout, ","), 3, int_variate_generator);
    return 0;
}

最新更新