random - C++ 標準程式庫

文章推薦指數: 80 %
投票人數:10人

標頭中,有多個選項可供選擇,而且其中任何選項都優於過期的C Runtime 函式 rand() 。

如需 rand() 所發生錯誤以及 如何解決這些 ... 跳到主要內容 已不再支援此瀏覽器。

請升級至MicrosoftEdge,以利用最新功能、安全性更新和技術支援。

下載MicrosoftEdge 其他資訊 目錄 結束焦點模式 語言 閱讀英文 儲存 目錄 閱讀英文 儲存 Twitter LinkedIn Facebook 電子郵件 WeChat 目錄 發行項 05/02/2022 10位參與者 此頁面有所助益嗎? Yes No 還有其他意見反應嗎? 系統會將意見反應傳送給Microsoft:按下[提交]按鈕,您的意見反應將用來改善Microsoft產品和服務。

隱私權原則。

送出 謝謝。

本文內容 定義亂數產生工具,允許建立統一分佈的亂數。

規格需求 標頭: 命名空間:std 注意 連結庫使用'#include'語句。

總結 「亂數產生器」是一個物件,可產生一連串的虛擬隨機值。

產生統一分佈於指定範圍之值的產生器是「統一亂數產生器」(UniformRandomNumberGenerator,URNG)。

設計為做為URNG的類別範本,如果該類別具有特定的通用特性,則稱為引擎,本文稍後會加以討論。

一般而言,URNG可以與「分佈」合併使用,方法是將URNG做為引數傳遞至分佈的operator(),以產生由分佈所定義的方式而分佈的值。

這些連結會跳到本文的主要小節: 範例 分類清單 引擎和分佈 備註 快速提示 以下是使用時要記住的一些提示: 在大部分的用途中,URNG都會產生必須由分佈所圖形化的原始位元(值得注意的例外狀況是std::shuffle()因為它直接使用URNG。

) 因為執行URNG或分佈是修改作業,所以無法安全地同時呼叫URNG或分佈的單一具現化。

如需詳細資訊,請參閱C++標準程式庫中的執行緒安全。

提供數個引擎的預先定義typedef;如果使用引擎,這是建立URNG的慣用方式。

大部分應用程式的最實用配對是mt19937引擎搭配uniform_int_distribution(如本文稍後的程式碼範例所示)。

標頭中,有多個選項可供選擇,而且其中任何選項都優於過期的CRuntime函式rand()。

如需rand()所發生錯誤以及如何解決這些缺點的詳細資訊,請參閱本影片。

範例 下列程式碼範例示範如何產生一些亂數,在此情況下,其中有五個使用以不具決定性的種子建立的產生器。

#include #include usingnamespacestd; intmain() { random_devicerd;//non-deterministicgenerator mt19937gen(rd());//toseedmersennetwister. //replacethecalltord()witha //constantvaluetogetrepeatable //results. for(inti=0;i<5;++i){ cout< #include usingnamespacestd; intmain() { random_devicerd;//non-deterministicgenerator mt19937gen(rd());//toseedmersennetwister. uniform_int_distribution<>dist(1,6);//distributeresultsbetween1and6inclusive. for(inti=0;i<5;++i){ cout< #include #include #include #include #include #include//ref() usingnamespacestd; templatevoidprint(constC&c){ for(constauto&e:c){ cout< voidtest(URNG&urng){ //Uniformdistributionusedwithavector //Distributionis[-5,5]inclusive uniform_int_distributiondist(-5,5); vectorv; for(inti=0;i<20;++i){ v.push_back(dist(urng)); } cout<arr={{"H","He","Li","Be","B","C","N","O","F", "Ne","Na","Mg","Al","Si","P","S","Cl","Ar","K","Ca","Sc", "Ti","V","Cr","Mn","Fe"}}; shuffle(arr.begin(),arr.end(),urng); cout<seed_data; generate_n(seed_data.begin(),seed_data.size(),ref(rd)); seed_seqseq(begin(seed_data),end(seed_data)); mt19937engine3(seq); test(engine3); } Usingrandom_deviceURNG: Randomizedvector:5-42305-2042-12-4-314412-2 Randomizedarray:OLiVKCTiNMgNeScClBCrMnCaAlFPNaBeSiArFeSHeH -- Usingconstant-seedmersennetwisterURNG: Randomizedvector:3-1-50053-4-3-41-30-3-2-451-1-1 Randomizedarray:AlONeSiNaBeCNCrMnHVFScMgFeKCaSTiBPArClLiHe -- Usingnon-deterministic-seedmersennetwisterURNG: Randomizedvector:5-4021-244-4004-54-5-1-3003 Randomizedarray:SiFeAlArNaPBScHFMgLiCTiHeNMnBeOCaCrVKNeClS -- Usingnon-deterministic-seed"warm-up"sequencemersennetwisterURNG: Randomizedvector:-13-24130-55-50050-33-4250 Randomizedarray:SiCScHNaOSCrKLiAlTiClBMnHeFeNeBeArVPCaNMgF -- 此程式碼使用測試範本函式,示範兩個不同的隨機:隨機化整數向量,並隨機播放已編製索引資料的陣列。

測試函式的第一次呼叫會使用具有加密保護,且不具決定性、不可植入、不可重複的URNGrandom_device。

第二個測試回合使用mersenne_twister_engine做為URNG,並搭配決定性32位元常數種子,這表示結果是可重複的。

第三個測試回合將來自mersenne_twister_engine的32位元不具決定性結果植入random_device。

第四個測試回合透過使用填入random_device結果的種子序列,將此情況延伸,這可以有效地提供比32位元更多的不具決定性隨機性(但還是不具加密保護)。

如需詳細資訊,請繼續閱讀本文。

分類清單 統一亂數產生器 通常會根據這些屬性描述URNG: 期間長度:它使用多少個反覆項目來重複一串產生的數字序列。

愈長愈好。

效能:產生數字的速度,以及使用多少記憶體。

愈小愈好。

品質:產生的序列有多接近真正亂數。

這通常稱為「隨機性」。

下列各節列出標頭中提供的統一亂數產生器(URNG)。

不具決定性產生器 random_device類 使用外部裝置,產生不具決定性且以加密編譯方式保護的隨機序列。

通常用於植入引擎。

低效能,品質很高。

如需詳細資訊,請參閱。

具有預先定義參數的引擎Typedef 用於具現化引擎和引擎配接器。

如需詳細資訊,請參閱引擎和分佈。

default_random_engine:預設的引擎。

typedefmt19937default_random_engine; knuth_b:Knuth引擎。

typedefshuffle_order_engineknuth_b; minstd_rand0:1988最低標準引擎(Lewis、Goodman及Miller,1969年)。

typedeflinear_congruential_engineminstd_rand0; minstd_rand:更新的最低標準引擎minstd_rand0(Park、Miller及Stockmeyer,1993年)。

typedeflinear_congruential_engineminstd_rand; mt19937:32位元梅森旋轉引擎(Matsumoto和Nishimura,1998年)。

typedefmersenne_twister_engine< unsignedint,32,624,397, 31,0x9908b0df, 11,0xffffffff, 7,0x9d2c5680, 15,0xefc60000, 18,1812433253>mt19937; mt19937_64:64位元梅森旋轉引擎(Matsumoto和Nishimura,2000年)。

typedefmersenne_twister_engine< unsignedlonglong,64,312,156, 31,0xb5026f5aa96619e9ULL, 29,0x5555555555555555ULL, 17,0x71d67fffeda60000ULL, 37,0xfff7eee000000000ULL, 43,6364136223846793005ULL>mt19937_64; ranlux2424位RANLUX引擎(MartinLüscher和FredJames,1994)。

typedefdiscard_block_engineranlux24; ranlux24_base:用做ranlux24的基底。

typedefsubtract_with_carry_engineranlux24_base; ranlux4848位RANLUX引擎(MartinLüscher和FredJames,1994)。

typedefdiscard_block_engineranlux48; ranlux48_base:用做ranlux48的基底。

typedefsubtract_with_carry_engineranlux48_base; 引擎範本 引擎範本用做獨立URNG,或用做傳遞給引擎配接器的基底引擎。

這些通常使用預先定義的引擎typedef進行具現化,並傳遞給分佈。

如需詳細資訊,請參閱引擎和分佈一節。

名稱 描述 linear_congruential_engine類 使用線性同餘演算法,產生隨機序列。

最為簡單且品質最低。

mersenne_twister_engine類 使用梅森旋轉演算法,產生隨機序列。

最為複雜,但品質最高(random_device類別除外)。

效能極為快速。

subtract_with_carry_engine類 使用帶進位減法演算法,以產生隨機序列。

改善linear_congruential_engine,但是品質和效能比mersenne_twister_engine還要低。

引擎配接器範本 引擎配接器是可配接其他(基底)引擎的範本。

這些通常使用預先定義的引擎typedef進行具現化,並傳遞給分佈。

如需詳細資訊,請參閱引擎和分佈一節。

名稱 描述 discard_block_engine類 捨棄其基底引擎所傳回的值,以產生隨機序列。

independent_bits_engine類 重新封裝其基底引擎所傳回之值的位元,以產生具有指定位元數的隨機序列。

shuffle_order_engine類 透過重新排列基底引擎傳回的值產生隨機序列。

[引擎範本] 亂數分佈 下列各節列出標頭中提供的分佈。

分佈是一個後續處理機制,通常使用URNG輸出做為輸入,並透過定義的統計可能性密度函式來散發輸出。

如需詳細資訊,請參閱引擎和分佈一節。

統一分佈 名稱 描述 uniform_int_distribution類 在封閉間隔[a,b]中產生範圍中的統一整數值分佈,(內含)。

uniform_real_distribution類 產生跨半開間隔[a,b)(內含-排除)中某個範圍的統一實數(浮點)值分佈。

generate_canonical 產生跨[0,1)(內含-排除)之指定精確度的實數(浮點)值平均分佈。

[亂數分佈] 白努利分佈 名稱 描述 bernoulli_distribution類 產生bool值的白努利分佈。

binomial_distribution類 產生整數值的二項式分佈。

geometric_distribution類 產生整數值的幾何分佈。

negative_binomial_distribution類 產生整數值的負二項式分佈。

[亂數分佈] 常態分佈 名稱 描述 cauchy_distribution類 產生實數(浮點)值的柯西分佈。

chi_squared_distribution類 產生實數(浮點)值的卡方分佈。

fisher_f_distribution類 產生F分佈(也稱為Snedecor的F分佈,或實際(浮點數)值的Fisher-Snedecor分佈)。

lognormal_distribution類 產生實數(浮點)值的對數常態分佈。

normal_distribution類 產生實數(浮點)值的常態(高斯)分佈。

student_t_distribution類 產生實數(浮點)值的學生t分佈。

[亂數分佈] 波氏分佈 名稱 描述 exponential_distribution類 產生實數(浮點)值的指數分佈。

extreme_value_distribution類 產生實數(浮點)值的極值分佈。

gamma_distribution類 產生實數(浮點)值的Gamma分佈。

poisson_distribution類 產生整數值的波氏分佈。

weibull_distribution類 產生實數(浮點)值的Weibull分佈。

[亂數分佈] 取樣分佈 名稱 描述 discrete_distribution類 產生離散整數分佈。

piecewise_constant_distribution類 產生實數(浮點)值的分段常數分佈。

piecewise_linear_distribution類 產生實數(浮點)值的分段線性分佈。

[亂數分佈] 公用程式函數 本節列出標頭中提供的一般公用程式函式。

名稱 描述 seed_seq類 產生無偏差干擾種子序列。

用來避免複寫隨機變量資料流。

從引擎具現化許多URNG時十分有用。

運算子 本節列出標頭中提供的運算子。

名稱 描述 operator== 測試運算子左邊的URNG是否等於右邊的引擎。

operator!= 測試運算子左邊的URNG是否不等於右邊的引擎。

operator<< 將狀態資訊寫入資料流。

operator>> 從資料流中擷取狀態資訊。

引擎和分佈 如需中定義之每個類別範本類別目錄的相關資訊,請參閱下列各節。

這兩個類別範本類別都會採用類型作為引數,並使用共用範本參數名稱來描述允許做為實際引數類型的類型屬性,如下所示: IntType指出short、int、long、longlong、unsignedshort、unsignedint、unsignedlong或unsignedlonglong。

UIntType指出unsignedshort、unsignedint、unsignedlong或unsignedlonglong。

RealType指出float、double或longdouble。

引擎 引擎範本和引擎配接器範本是其參數會自訂所建立之產生器的範本。

引擎是類別或類別範本,其實例(產生器)作為最小和最大值之間統一分配的亂數來源。

「引擎配接器」會採用部分其他亂數引擎所產生的值,並將某種類型的演算法套用至那些值,以傳遞一連串具有不同隨機性屬性的值。

每個引擎和引擎配接器都具有下列成員: typedefnumeric-typeresult_type是產生器operator()傳回的類型。

在具現化時,會將numeric-type傳遞為範本參數。

result_typeoperator()會傳回統一分佈在min()與max()之間的值。

result_typemin()會傳回產生器的operator()所傳回的最小值。

引擎配接器會使用基底引擎的min()結果。

result_typemax()會傳回產生器的operator()所傳回的最大值。

result_type是整數(整數值)類型時,max()是可以實際傳回的最大值(內含);result_type是浮點(實數值)類型時,max()是大於可傳回之所有值的最小值(非內含)。

引擎配接器會使用基底引擎的max()結果。

voidseed(result_types)會使用種子值s植入產生器。

針對引擎,預設參數支援的簽章是voidseed(result_types=default_seed)(引擎配接器會定義個別voidseed(),請參閱下一個小節)。

templatevoidseed(Seq&q)使用seed_seqSeq植入產生器。

具有引數result_typex的明確建構函式,會建立植入的產生器,就像藉由呼叫seed(x)一樣。

具有引數seed_seq&seq的明確建構函式,會建立植入的產生器,就像藉由呼叫seed(seq)一樣。

voiddiscard(unsignedlonglongcount)會有效率地呼叫operator()count次,並捨棄每個值。

引擎配接器額外支援這些成員(Engine是引擎配接器的第一個範本參數,會指定基底引擎類型): 初始化產生器的預設建構函式,就像來自基底引擎的預設建構函式一樣。

引數為constEngine&eng的明確建構函式。

這是使用基底引擎來支援複製建構函式。

引數為Engine&&eng的明確建構函式。

這是使用基底引擎來支援移動建構函式。

使用基底引擎預設種子值來初始化產生器的voidseed()。

傳回用於建構產生器之基底引擎的constEngine&base()屬性函式。

每個引擎都會維護一個「狀態」,而狀態會決定後續呼叫operator()所產生的值序列。

使用operator==和operator!=,可以比較從相同類型的引擎具現化的兩個產生器的狀態。

如果兩種狀態比較為相等,則會產生相同的值序列。

使用產生器的operator<>,可以將儲存的狀態讀取至從相同類型的引擎具現化的產生器。

散發 亂數分佈是類別或類別範本,其實例會將從引擎取得的統一分散式亂數資料流程轉換成具有特定分佈的亂數資料流程。

每個分佈都有下列成員: typedefnumeric-typeresult_type是分佈的operator()所傳回的類型。

在具現化時,會將numeric-type傳遞為範本參數。

templateresult_typeoperator()(URNG&gen)會傳回根據分佈定義所分佈的值,方法是使用gen做為統一分佈隨機值的來源,以及儲存之「分佈的參數」。

templateresult_typeoperator()(URNG&gen,param_typep)會傳回按照分佈定義所分佈的值,方法是使用gen做為統一分佈隨機值的來源,以及參數結構p。

typedefunspecified-typeparam_type是選擇性地傳遞至operator()的參數封裝,以及用來取代儲存的參數以產生其傳回值。

constparam&建構函式會從其引數初始化儲存的參數。

param_typeparam()const取得儲存的參數。

voidparam(constparam_type&)會從其引數設定儲存的參數。

result_typemin()會傳回分佈的operator()所傳回的最小值。

result_typemax()會傳回分佈的operator()所傳回的最大值。

result_type是整數(整數值)類型時,max()是可以實際傳回的最大值(內含);result_type是浮點(實數值)類型時,max()是大於可傳回之所有值的最小值(非內含)。

voidreset()會捨棄任何快取的值,讓下個operator()呼叫的結果不是取決於呼叫之前取自引擎的任何值。

參數結構是一個物件,其中儲存分佈所需的所有參數。

它包含: typedefdistribution-typedistribution_type,這是其分佈的類型。

一個或多個建構函式,採用與分佈建構函式所採用的相同參數清單。

與分佈相同的參數存取函式。

等號和不等比較運算子。

如需詳細資訊,請參閱本文之前的連結中,本主題下面的參考副主題。

備註 在VisualStudio中,有兩個極為有用的URNG(mt19937和random_device),如此比較表所示: URNG 快速 具有加密保護 可植入 具決定性 mt19937 是 否 是 是* random_device 否 是 否 否 *提供已知種子時。

雖然ISOC++標準不需要加密保護random_device,但在VisualStudio中,會將它實作為進行加密保護。

(「以密碼編譯方式保護」一詞並不表示保證,但是指最小層級的Entropy,因此,指定隨機化演算法提供的可預測性層級。

如需詳細資訊,請參閱維琪百科文章密碼編譯保護虛擬亂數產生器。

)因為ISOC++標準不需要此專案,其他平臺可能會實random_device作為簡單的虛擬亂數產生器,(不以密碼編譯方式安全),而且可能只適合做為另一個產生器的種子來源。

在跨平台程式碼中使用random_device時,請參閱哪些平台的文件。

透過定義,random_device結果是無法重新產生的,而且副作用是執行速度會明顯比其他URNG慢。

雖然您可能想要使用random_device呼叫來進行植入(如程式碼範例中所示),但大部分不需要加密保護的應用程式都會使用mt19937或類似的引擎。

另請參閱 標頭檔參考 本文內容



請為這篇文章評分?