【C++11】隨機(jī)值獲取——random

我們知道,C 中的隨機(jī)數(shù)函數(shù)只有一個 rand( ) ,想生成某一區(qū)間范圍內(nèi)的隨機(jī)數(shù)乃至隨機(jī)的浮點(diǎn)數(shù)都十分麻煩。

而 C++11 中提供的 random 庫解決了這一問題,它能讓我們方便地生成需要的隨機(jī)值。

下面將介紹如何利用 random 庫中的組件生成符合條件的隨機(jī)數(shù)。

random 庫中的組件分為兩類——隨機(jī)數(shù)引擎類和隨機(jī)數(shù)分布類。

隨機(jī)數(shù)引擎類是可以獨(dú)立運(yùn)行的隨機(jī)數(shù)發(fā)生器,它以均勻的概率生成某一類型的隨機(jī)數(shù),但無法指定隨機(jī)數(shù)的范圍、概率等信息。因此,它也被稱為“原始隨機(jī)數(shù)發(fā)生器”,由于不能指定生成隨機(jī)數(shù)的范圍,它通常不會被單獨(dú)使用。

隨機(jī)數(shù)分布類是一個需要于隨機(jī)數(shù)引擎類的支持才能運(yùn)行的類,但是它能根據(jù)用戶的需求利用隨機(jī)數(shù)引擎生成符合條件的隨機(jī)數(shù),例如某一區(qū)間、某一分布概率的隨機(jī)數(shù)。

所有隨機(jī)數(shù)引擎類都支持的操作如下:

名稱 功能
Engine e 創(chuàng)建一個引擎。
Engine e(s) 創(chuàng)建一個引擎,并用 s 作為種子。
e.seed(s) 使用種子 s 充值 e 的狀態(tài)。
e.min( ), e.max( ) e 能生成的最小值和最大值。
e.discard(u) 將 e 推進(jìn) u 步(u 的類型為 unsigned long long)。

下表隨機(jī)數(shù)分布類共有的操作:

名稱 功能
U u 創(chuàng)建一個分布類 u 。
u(e) 用隨機(jī)數(shù)引擎 e 生成隨機(jī)數(shù)(u 代表隨機(jī)數(shù)分布類)。
u.min( ) u 能生成的最小值。
u.max( ) u 能生成的最大值。
u.reset( ) 重置 u 的狀態(tài),使隨后 u 生成的值不受之前的值影響 。

隨機(jī)非負(fù)數(shù)——default_random_engine


default_random_engine 是一個隨機(jī)數(shù)引擎類。它定義的調(diào)用運(yùn)算符返回一個隨機(jī)的 unsigned 類型的值。

因此,若想生成 10 個隨機(jī)非負(fù)數(shù)并輸出,程序可以這么寫:

#include <iostream>
#include <random>
using namespace std;

int main( ){
    default_random_engine e;
    for(int i=0; i<10; ++i)
        cout<<e( )<<endl;
    return 0;
}

在我們的系統(tǒng)中,測試結(jié)果為:

16807
282475249
1622650073
984943658
1144108930
470211272
101027544
1457850878
1458777923
2007237709

可以看出,還是比較“隨機(jī)”的。

當(dāng)然,default_random_engine 也只是一個偽隨機(jī)數(shù)發(fā)生器,如果在運(yùn)行一次程序,得到結(jié)果將還是這幾個數(shù)。

若想令每次運(yùn)行程序時的生成結(jié)果不同,可以為其設(shè)置較為隨機(jī)的種子,比如當(dāng)前系統(tǒng)的時間。

特定范圍的非負(fù)數(shù)——uniform_int_distribution


uniform_int_distribution 是一個隨機(jī)數(shù)分布類,也是個模板類,模板參數(shù)為生成隨機(jī)數(shù)的類型(不過只能是 int、unsigned、short、unsigned short、long、unsigned long、long long、unsigned long long 中的一種)。它的構(gòu)造函數(shù)接受兩個值,表示隨機(jī)數(shù)的分布范圍(閉區(qū)間)。

因此,一個生成 0 到 9 的隨機(jī)數(shù)程序可以這么寫:

#include <iostream>
#include <random>
using namespace std;

int main( ){
    default_random_engine e;
    uniform_int_distribution<unsigned> u(0, 9);
    for(int i=0; i<10; ++i)
        cout<<u(e)<<endl;
    return 0;
}

在我們的系統(tǒng)中,它的生成結(jié)果為:

0     
1     
7     
4     
5     
2     
0     
6     
6     
9     

隨機(jī)浮點(diǎn)數(shù)——uniform_real_distribution


uniform_real_distribution 是一個隨機(jī)數(shù)分布類,它也是模板類,參數(shù)表示隨機(jī)數(shù)類型(可選類型為 float、double、long double)。構(gòu)造函數(shù)也需要最大值和最小值作為參數(shù)。

下面是一個生成 10 個 0~1 之間的隨機(jī)浮點(diǎn)數(shù)的例子:

#include <iostream>
#include <random>
using namespace std;

int main( ){
    default_random_engine e;
    uniform_real_distribution<double> u(0.0, 1.0);
    for(int i=0; i<10; ++i)
        cout<<u(e)<<endl;
    return 0;
}

在我們的系統(tǒng)上的結(jié)果為:

0.131538
0.45865
0.218959
0.678865
0.934693
0.519416
0.0345721
0.5297
0.00769819
0.0668422

隨機(jī)布爾值——bernoulli_distribution


bernoulli_distribution 是一個分布類,但它不是模板類。它的構(gòu)造函數(shù)只有一個參數(shù),表示該類返回 true 的概率,該參數(shù)默認(rèn)為 0.5 ,即返回 true 和 false 的概率相等。

下面是一個生成 10 個隨機(jī)布爾值的例子:

#include <iostream>
#include <random>
using namespace std;

int main( ){
    default_random_engine e;
    bernoulli_distribution u;
    for(int i=0; i<10; ++i)
        cout<<u(e)<<endl;
    return 0;
}

在我們的系統(tǒng)上的結(jié)果為:

1
1
1
0
0
0
1
0
1
1

總結(jié)


常用的隨機(jī)數(shù)類如下:

  • default_random_engine:隨機(jī)非負(fù)數(shù)(不建議單獨(dú)使用)。
  • uniform_int_distribution:指定范圍的隨機(jī)非負(fù)數(shù)。
  • uniform_real_distribution:指定范圍的隨機(jī)實(shí)數(shù)。
  • bernoulli_distribution:指定概率的隨機(jī)布爾值。

事實(shí)上,random 庫的功能極其豐富,其中的隨機(jī)數(shù)引擎不止有 default_random_engine 一個,分布類也遠(yuǎn)遠(yuǎn)不止上述三個。它還能進(jìn)行泊松分布、正態(tài)分布、抽樣分等高級的隨機(jī)數(shù)功能,想詳細(xì)了解這些內(nèi)容請去查閱其他資料。我可能要等好久才能把這些內(nèi)容補(bǔ)上。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容