我們知道升熊,C 中的隨機(jī)數(shù)函數(shù)只有一個(gè) rand( )
俄烁,想生成某一區(qū)間范圍內(nèi)的隨機(jī)數(shù)乃至隨機(jī)的浮點(diǎn)數(shù)都十分麻煩。
而 C++11 中提供的 random
庫(kù)解決了這一問(wèn)題级野,它能讓我們方便地生成需要的隨機(jī)值页屠。
下面將介紹如何利用 random
庫(kù)中的組件生成符合條件的隨機(jī)數(shù)。
random
庫(kù)中的組件分為兩類——隨機(jī)數(shù)引擎類和隨機(jī)數(shù)分布類蓖柔。
隨機(jī)數(shù)引擎類是可以獨(dú)立運(yùn)行的隨機(jī)數(shù)發(fā)生器辰企,它以均勻的概率生成某一類型的隨機(jī)數(shù),但無(wú)法指定隨機(jī)數(shù)的范圍渊抽、概率等信息蟆豫。因此,它也被稱為“原始隨機(jī)數(shù)發(fā)生器”懒闷,由于不能指定生成隨機(jī)數(shù)的范圍十减,它通常不會(huì)被單獨(dú)使用。
隨機(jī)數(shù)分布類是一個(gè)需要于隨機(jī)數(shù)引擎類的支持才能運(yùn)行的類愤估,但是它能根據(jù)用戶的需求利用隨機(jī)數(shù)引擎生成符合條件的隨機(jī)數(shù)帮辟,例如某一區(qū)間、某一分布概率的隨機(jī)數(shù)玩焰。
所有隨機(jī)數(shù)引擎類都支持的操作如下:
名稱 | 功能 |
---|---|
Engine e | 創(chuàng)建一個(gè)引擎由驹。 |
Engine e(s) | 創(chuàng)建一個(gè)引擎,并用 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)建一個(gè)分布類 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
是一個(gè)隨機(jī)數(shù)引擎類勉躺。它定義的調(diào)用運(yùn)算符返回一個(gè)隨機(jī)的 unsigned
類型的值癌瘾。
因此,若想生成 10 個(gè)隨機(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)中妨退,測(cè)試結(jié)果為:
16807
282475249
1622650073
984943658
1144108930
470211272
101027544
1457850878
1458777923
2007237709
可以看出,還是比較“隨機(jī)”的蜕企。
當(dāng)然碧注,default_random_engine
也只是一個(gè)偽隨機(jī)數(shù)發(fā)生器,如果在運(yùn)行一次程序糖赔,得到結(jié)果將還是這幾個(gè)數(shù)萍丐。
若想令每次運(yùn)行程序時(shí)的生成結(jié)果不同,可以為其設(shè)置較為隨機(jī)的種子放典,比如當(dāng)前系統(tǒng)的時(shí)間逝变。
特定范圍的非負(fù)數(shù)——uniform_int_distribution
uniform_int_distribution
是一個(gè)隨機(jī)數(shù)分布類,也是個(gè)模板類奋构,模板參數(shù)為生成隨機(jī)數(shù)的類型(不過(guò)只能是 int壳影、unsigned、short弥臼、unsigned short宴咧、long、unsigned long径缅、long long掺栅、unsigned long long 中的一種)。它的構(gòu)造函數(shù)接受兩個(gè)值纳猪,表示隨機(jī)數(shù)的分布范圍(閉區(qū)間)氧卧。
因此,一個(gè)生成 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
是一個(gè)隨機(jī)數(shù)分布類沙绝,它也是模板類,參數(shù)表示隨機(jī)數(shù)類型(可選類型為 float、double闪檬、long double)星著。構(gòu)造函數(shù)也需要最大值和最小值作為參數(shù)。
下面是一個(gè)生成 10 個(gè) 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è)分布類粗悯,但它不是模板類强饮。它的構(gòu)造函數(shù)只有一個(gè)參數(shù),表示該類返回 true 的概率为黎,該參數(shù)默認(rèn)為 0.5 ,即返回 true 和 false 的概率相等行您。
下面是一個(gè)生成 10 個(gè)隨機(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
庫(kù)的功能極其豐富捌斧,其中的隨機(jī)數(shù)引擎不止有 default_random_engine
一個(gè)笛质,分布類也遠(yuǎn)遠(yuǎn)不止上述三個(gè)。它還能進(jìn)行泊松分布捞蚂、正態(tài)分布妇押、抽樣分等高級(jí)的隨機(jī)數(shù)功能,想詳細(xì)了解這些內(nèi)容請(qǐng)去查閱其他資料姓迅。我可能要等好久才能把這些內(nèi)容補(bǔ)上敲霍。