c++ - 我如何使用 Boost Random

标签 c++ boost boost-random

<分区>

我需要使用 Boost Random 生成随机数。

我试着遵循一般指南。

我提取了图书馆的文件。那么如果我想使用库的classes和objectj应该怎么办呢?

首先我知道在程序中包含库。然后我必须编译库和 program.cpp 本身? (并且都使用相同的编译器——我使用的是 g++)。

我使用的是 ubuntu 虚拟机。这是我第一次使用库,所以我真的不知道。

最佳答案

the random number for my case must be double not just integer...

因此,您使用实数分布。


我不是说这种“入门”最适合 StackOverflow,但我会给你这个快速提示:

在你的 Ubuntu 虚拟盒子中:

sudo apt-get install libboost-all-dev
mkdir -pv ~/myproject
cd ~/myproject

使用您喜欢的编辑器创建一个文件。如果你没有,gedit main.cppnano main.cpp 是一个开始:

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

int main() {
    boost::random::mt19937 rng;                                        
    boost::random::uniform_real_distribution<double> gen(0.0, 1.0);
    for (int i = 0; i < 10; ++i) {
        std::cout << gen(rng) << "\n";
    }
}

现在编译它使用

g++ -O2 -Wall -Wextra -pedantic main.cpp -o demo

程序现在可以运行了: Live On Coliru

./demo

打印

0.814724
0.135477
0.905792
0.835009
0.126987
0.968868
0.913376
0.221034
0.632359
0.308167

播种 && 仅非 header 库

上面的代码之所以有效,是因为 Boost Random 库主要只是 header 。如果您想使用 random_device 实现来为随机生成器设置种子怎么办?

Live On Coliru

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

int main() {
    boost::random::random_device seeder;
    boost::random::mt19937 rng(seeder());                                        
    boost::random::uniform_real_distribution<double> gen(0.0, 1.0);
    for (int i = 0; i < 10; ++i) {
        std::cout << gen(rng) << "\n";
    }
}

现在您还必须链接:编译

g++ -O2 -Wall -Wextra -pedantic main.cpp -o demo -lboost_random

现在每次运行的输出都会不同。

奖励:标准库而不是 Boost

这里根本不需要 Boost:

Live On Coliru

#include <random>
#include <iostream>

int main() {
    std::random_device seeder;
    std::mt19937 rng(seeder());                                        
    std::uniform_real_distribution<double> gen(0.0, 1.0);
    for (int i = 0; i < 10; ++i) {
        std::cout << gen(rng) << "\n";
    }
}

编译

g++ -std=c++11 -O2 -Wall -Wextra -pedantic main.cpp -o demo

然后用./demo再次运行它

奖金

显示均值为 0 且标准偏差为 1 的整个分布范围:

Live On Coliru

#include <random>
#include <iostream>
#include <iomanip>
#include <chrono>
#include <boost/serialization/array_wrapper.hpp>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>

namespace ba = boost::accumulators;
using Accum = ba::accumulator_set<double, ba::stats<ba::tag::variance, ba::tag::mean> >;
using Clock = std::chrono::high_resolution_clock;
using namespace std::chrono_literals;

static double identity(double d) { return d; }

template <typename Prng, typename Dist, typename F = double(double), size_t N = (1ull << 22)>
void test(Prng& rng, Dist dist, F f = &identity) {
    Accum accum;

    auto s = Clock::now();
    for (size_t i = 0; i<N; ++i)
        accum(f(dist(rng)));

    std::cout 
        << std::setw(34) << typeid(Dist).name() 
        << ":\t" << ba::mean(accum) 
        << " stddev: " << sqrt(ba::variance(accum)) 
        << " N=" << N 
        << " in " << ((Clock::now()-s)/1.s) << "s"
        << std::endl;
}

int main() {
    std::mt19937 rng(std::random_device{}());                                        

    auto shift = [](double shift) { return [=](double v) { return v + shift; }; };
    auto scale = [](double scale) { return [=](double v) { return v * scale; }; };

    std::cout << std::fixed << std::showpos;
    test(rng, std::uniform_real_distribution<double>(-sqrt(3), sqrt(3)));
    test(rng, std::weibull_distribution<double>(), shift(-1));
    test(rng, std::exponential_distribution<double>(), shift(-1));
    test(rng, std::normal_distribution<double>());
    test(rng, std::lognormal_distribution<double>(0, log(0.5)), shift(-exp(pow(log(0.5),2)/2)));
    test(rng, std::chi_squared_distribution<double>(0.5), shift(-0.5));
    {
        auto sigma = sqrt(6)/M_PI;
        static constexpr double ec = 0.57721566490153286060;
        test(rng, std::extreme_value_distribution<double>(-sigma*ec, sigma));
    }
    test(rng, std::fisher_f_distribution<double>(48, 8), shift(-(8.0/6.0)));
    test(rng, std::student_t_distribution<double>(4), scale(sqrt(0.5)));
    test(rng, std::student_t_distribution<double>(4), scale(sqrt(0.5)));
}

打印

  St25uniform_real_distributionIdE: +0.000375 stddev: +1.000056 N=4194304 in +0.169681s
       St20weibull_distributionIdE: +0.001030 stddev: +1.000518 N=4194304 in +0.385036s
   St24exponential_distributionIdE: -0.000360 stddev: +1.000343 N=4194304 in +0.389443s
        St19normal_distributionIdE: -0.000133 stddev: +1.000330 N=4194304 in +0.390235s
     St22lognormal_distributionIdE: +0.000887 stddev: +1.000372 N=4194304 in +0.521975s
   St24chi_squared_distributionIdE: -0.000092 stddev: +0.999695 N=4194304 in +1.233835s
 St26extreme_value_distributionIdE: -0.000381 stddev: +1.000242 N=4194304 in +0.611973s
      St21fisher_f_distributionIdE: -0.000073 stddev: +1.001588 N=4194304 in +1.326189s
     St22student_t_distributionIdE: +0.000957 stddev: +0.998087 N=4194304 in +1.080468s
     St22student_t_distributionIdE: +0.000677 stddev: +0.998786 N=4194304 in +1.079066s

关于c++ - 我如何使用 Boost Random,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48598151/

相关文章:

c++ - 访问数据成员(本身是对象)的数据成员,就好像它们是类成员一样

c++ - 使用 qt 浏览、列出和删除文件

c++ - boost RNG 的线程安全

c++ - 无法使用 VAO 和 EBO (openGL) 绘制多个对象

c++ - 编译器对重载次数的限制?

c++ - 如何在 Xcode 中使用 boost::multiprecision::float128

c++ - 使用 boost::random 从要删除元素的 std::list 中进行选择

gcc - boost::uniform_on_sphere 在几百万次正确实现后突然失败,但仅限于某些主机

xcode - Boost.Python - 即使链接了 lib 文件,也会出现 undefined symbol 错误

c++ - Boost 和 Python 3.x