Boost隨機庫的簡單使用:Boost.Random(STL通用)
阿新 • • 發佈:2020-12-05
[//]:#(Boost隨機庫的簡單使用:Boost.Random(STL通用))
### 文章目錄
- [文章目錄](#文章目錄)
- [文章內容介紹](#文章內容介紹)
- [Boost隨機庫的簡單使用](#boost隨機庫的簡單使用)
- [生成一個隨機的整數](#生成一個隨機的整數)
- [生成一個區間的平均概率隨機數](#生成一個區間的平均概率隨機數)
- [按概率生成一個區間的隨機整數](#按概率生成一個區間的隨機整數)
- [一些經典的分佈](#一些經典的分佈)
- [與STL的對比](#與stl的對比)
- [Ref](#ref)
---
### 文章內容介紹
Boost.Random是Boost裡面的一個隨機庫,它的第一正式版是在Boost 1.15中提供。它裡面提供了大量的隨機演算法,比如mt19937演算法,加權概率,隨機密碼等。可以很方便的提高編碼效率。
本文主要介紹了Boost.Random的一些簡單使用本文主要分為四個部分,第一部分為此簡單介紹,第二部分為Boost.Random的使用,第四部分為總結。
本文參考的Boost版本為1.74。
### Boost隨機庫的簡單使用
#### 生成一個隨機的整數
```C++
boost::random::mt19937 gen(time((time_t *)NULL));
std::cout << gen() << std::endl;
```
首先構造一個隨機數生成器,這裡我們使用[mt19937演算法](https://zh.wikipedia.org/wiki/%E6%A2%85%E6%A3%AE%E6%97%8B%E8%BD%AC%E7%AE%97%E6%B3%95)的隨機數生成器。然後直接將隨機數生成器作為一個函式物件使用,便可以得到一個區間為$[0, 2^{32}-1]$的隨機數。
如果要生成64位的隨機數,可以使用`boost::random:mt19937_64`。相應的,它可以產生區間為$[0, 2^{64}] - 1$的隨機數。
除了mt19937演算法以外,Boost.Random還提供了非常多種的平均隨機數演算法,譬如`minstd_rand0`、`minstd_rand`、`rand48`、`ecuyer1988`、`knuth_b`等。
![](https://img2020.cnblogs.com/blog/2105008/202012/2105008-20201205113957110-742880667.png)
除了使用演算法生成一個偽隨機數外,Boost還提供了一個介面`random_device`,可以產生真·隨機數。它依賴於系統提供的硬體隨機,比如在Linux下會使用`/dev/urandom`。理論上來說,提供的硬體隨機應該是不會產生錯誤,或者讀取到結尾的。如果發生了,便會丟擲`std::io_base::failure`異常。使用`entropy`方法可以獲得隨機數生成器的熵值。
#### 生成一個區間的平均概率隨機數
一般情況下,我們都是需要生成一個區間內的隨機數,這才有一定的使用價值。在C語言中,我們通過以下方法獲得
```C
rand()%(upper_bound - lower_bound) + lower_bound
```
而在Boost中,它為我們提供了一個方法,可以通過定義分佈的方法,來生成一個區間的隨機整數。
```C++
boost::random::uniform_int_distribution<> dis(1, 6);
std::cout << dis(gen) << std::endl;
```
首先我們定義了一個分佈,從這個類的名稱我們就可以知道,這是一個平均的整數分佈。分佈和生成器一樣,是一個函式物件,通過輸入一個隨機數生成器,就可以得到隨機區域內的整數。生成的範圍為$[min, max]$
生成隨機實數也是類似,生成的範圍為$[min, max)$
```C++
boost::random::uniform_real_distribution<> fdis(0, 2);
std::cout << fdis(gen) << std::endl;
```
除了這些比較常用的平均分佈外,Boost還提供了兩種使用次數比較多的平均分佈:
1. `uniform_smallint`,它和`uniform_int_distribution`類似,不過這個分佈要求生成的範圍要遠小於隨機數生成器的範圍;
2. `uniform_01` 產生$[0, 1)$之間的隨機數。
#### 按概率生成一個區間的隨機整數
這種情況如果使用C語言實現,一般會是這樣操作。
```C
// 選擇的概率,選擇的資料為[0,3]
double prob = {0.1, 0.2, 0.3, 0.4};
double choose_prob = (random() % 100000)/100000.0;
choosed_number = 0;
for (choosed_number = 0; choosed_number < 4; ++choosed_number) {
choose_prob -= prob[choosed_number];
if (choose_prob < 0) break;
}
```
此時,choosed_number為選擇的資料。在Boost.Random中,提供了更為優雅的方法,來實現這一操作。
```C++
boost::random::discrete_distribution<> prob_dis({0.1, 0.2, 0.3, 0.4});
std