四时宝库

程序员的知识宝库

C++ 比较随机数生成器(c语言比较10个随机数的大小)

比较随机数生成器

随机库提供了一系列随机数生成器,每种生成器都有不同的策略和属性。在本示例中,我们将通过创建一个输出直方图来比较这些不同的选项。

如何做……

在本示例中,我们将比较C++随机库提供的不同随机数生成器:

我们首先定义一些常量,为随机数生成器提供统一的参数:

constexpr size_t n_samples{ 1000 };  
constexpr size_t n_partitions{ 10 };  
constexpr size_t n_max{ 50 };


n_samples 是要检查的样本数,n_partitions 是要在其中显示样本的分区数,n_max 是直方图中条形的最大大小(由于四舍五入,这会有所不同)。

这些数字提供了引擎之间差异的合理显示。增加样本数与分区数的比率往往会平滑曲线,并掩盖引擎之间的差异。

这是收集随机数样本并显示直方图的函数:

template <typename RNG>  
void histogram(const string_view& rng_name) {  
    auto p_ratio = (double)RNG::max() / n_partitions;  
    RNG rng{}; // 构造引擎对象  
  
    // 收集样本  
    vector<size_t> v(n_partitions);  
    for(size_t i{}; i < n_samples; ++i) {  
        ++v[rng() / p_ratio];  
    }  
  
    // 显示直方图  
    auto max_el = std::max_element(v.begin(), v.end());  
    auto v_ratio = *max_el / n_max;  
    if(v_ratio < 1) v_ratio = 1;  
    cout << format("engine: {}\n", rng_name);  
    for(size_t i{}; i < n_partitions; ++i) {  
        cout << format("{:02}:{:*<{}}\n",  
            i + 1, ' ', v[i] / v_ratio);  
    }  
    cout << '\n';  
}


简而言之,这个函数在向量中存储收集的样本的直方图,然后在控制台上以一系列星号显示直方图。

我们在main()中调用histogram()函数,如下所示:

int main() {  
    histogram<std::random_device>("random_device");  
    histogram<std::default_random_engine>("default_random_engine");  
    // ... 其他引擎的调用 ...  
}


输出:




如果我们将n_samples的值提高到100,000,您将发现引擎之间的差异变得更加难以区分:




它是如何工作的……

每个随机数引擎都有一个函数对象接口,用于返回序列中的下一个随机数:

result_type operator()();


函数对象返回一个随机值,该值在min()和max()值之间均匀分布。所有随机数引擎都共享此接口。

histogram()函数通过模板中使用随机数引擎的类来利用这种统一性:

template <typename RNG>


(RNG是随机数生成器的常见缩写。库文档将这些类称为引擎,这对我们的目的来说与RNG是同义词。)

我们使用RNG类实例化一个对象,并在向量中创建一个直方图:

RNG rng{};  
vector<size_t> v(n_partitions);  
for(size_t i{}; i < n_samples; ++i) {  
    ++v[rng() / p_ratio];  
}


这使得我们能够使用这种技术轻松比较各种随机数生成器的结果。

还有更多……

库中的每个随机数生成器都有不同的方法和特性。当您多次运行直方图时,您会注意到大多数引擎每次运行时都具有相同的分布。这是因为它们是确定性的——也就是说,它们每次都会生成相同的数字序列。std::random_device 在大多数系统上是非确定性的。如果您需要更多的变化,可以使用它来初始化其他引擎之一。使用当前日期和时间来初始化RNG也是很常见的做法。

std::default_random_engine 对于大多数目的来说都是一个合适的选择。

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接