C++中獲取隨機數(shù)的常用方法小結
1.C++中獲取隨機數(shù)的幾種方法
隨機數(shù)基本概念
隨機數(shù):在一定范圍內[a, z],每個數(shù)出現(xiàn)的概率相等并且無法預測下一個數(shù)的數(shù)值序列。
偽隨機數(shù)生成器(PRNG)
- 原理:由一個狀態(tài)寄存器和一個更新函數(shù)組成,初始狀態(tài)由種子決定,更新狀態(tài)會根據(jù)當前狀態(tài)生成下一個狀態(tài),并輸出一個偽隨機數(shù)
- 種子:偽隨機數(shù)生成器的初始值,決定了隨機數(shù)開始時的狀態(tài),由于隨機數(shù)基于算法與隨機數(shù)生成器初始時的狀態(tài)產(chǎn)生隨機序列,因此相同的種子產(chǎn)生完全相同的隨機序列
2. C++中獲取隨機數(shù)
2.1 基本流程
設置隨機數(shù)種子
獲取隨機數(shù)(整數(shù)、浮點數(shù))
2.2 隨機數(shù)種子來源
time()
函數(shù)
獲取當前時間戳,在多線程場景下,由于time函數(shù)的精度有限,可能產(chǎn)生相同的種子,生成相似的隨機序列
std::random_device
是一個非確定性的隨機數(shù)源,從操作系統(tǒng)或硬件設備重獲取真正的隨機信息
2.3獲取隨機數(shù)
C cstdlib庫中rand函數(shù)
#include <ctime> #include <cstdlib> #include <iostream> int main() { // 設置隨機數(shù)種子 std::srand(time(nullptr)); std::cout << "RAND_MAX" << RAND_MAX << std::endl; for (int i=0; i<10;++i) { // 獲取隨機數(shù) std::cout << "random value: " << rand() << std::endl; // 通過 % 取余獲取指定范圍的隨機數(shù) std::cout << "random range 1 100: " << rand() % 100 << std::endl; } };
C++ random庫 (c++11)
#include <random> #include <iostream> int main() { // 指定種子 std::default_random_engine engine(std::random_device{}()); int count = 10; // 指定范圍:整數(shù) std::uniform_int_distribution<int> rand_int_generator(0, 100); for (int i=0; i<10; ++i) { std::cout << "int random value:" << rand_int_generator(engine) << std::endl; } // 指定范圍:浮點數(shù) std::uniform_real_distribution<double> rand_double_generator(0, 1); for (int i=0; i<10; ++i) { std::cout << "double random value:" << rand_double_generator(engine) << std::endl; } };
隨機性要求較高使用 std::mt19937
作為引擎
#include <random> #include <iostream> int main() { // 指定種子 std::mt19937 engine(std::random_device{}()); int count = 10; // 指定范圍:整數(shù) std::uniform_int_distribution<int> rand_int_generator(0, 100); for (int i=0; i<10; ++i) { std::cout << "int random value:" << rand_int_generator(engine) << std::endl; } // 指定范圍:浮點數(shù) std::uniform_real_distribution<double> rand_double_generator(0, 1); for (int i=0; i<10; ++i) { std::cout << "double random value:" << rand_double_generator(engine) << std::endl; } };
3. Mersenne Twister (馬特賽特旋轉算法)
3.1工作原理
Mersenne Twister 算法維護一個內部狀態(tài)向量,這個向量的長度通常為 n個w -bit 的字。對于最常見的 MT19937
版本,n=624且w=32
初始化
首先使用一個種子(可以是任意整數(shù))初始化內部狀態(tài)向量。通常會對種子進行一些處理,將其擴展到內部狀態(tài)向量的長度
狀態(tài)更新
- 通過一個復雜的位操作函數(shù)對狀態(tài)向量進行更新,這個函數(shù)被稱為 “twist” 操作。在
MT19937
中,它使用了一系列的移位、異或和與操作,將狀態(tài)向量中的元素進行混合和更新 - 經(jīng)過多次 “twist” 操作,狀態(tài)向量中的元素會以一種復雜的方式發(fā)生變化,保證了下一個隨機數(shù)的不可預測性
隨機數(shù)提取
從更新后的狀態(tài)向量中提取隨機數(shù)。通常使用一個函數(shù)將狀態(tài)向量中的元素映射到所需的輸出范圍。例如,對于生成 32 位的隨機數(shù),直接使用狀態(tài)向量中的元素,而對于生成小于 32 位的隨機數(shù),則會對狀態(tài)向量中的元素進行適當?shù)慕財嗷蛭徊僮鱽砩伤璧碾S機數(shù)
3.2 特點
1.長周期
Mersenne Twister 的周期通常是 2^19937-1,這是一個巨大的數(shù)字,使得生成的隨機數(shù)序列非常長,能夠避免在實際應用中出現(xiàn)周期短導致的重復序列問題
2.高維均勻分布
生成的隨機數(shù)在高維空間中具有良好的均勻分布特性,這對于需要多個隨機數(shù)進行模擬或計算的情況非常重要
3.隨機性質量高
通過復雜的位操作和狀態(tài)轉移函數(shù)來產(chǎn)生隨機數(shù),克服了一些簡單隨機數(shù)生成器(如線性同余發(fā)生器)的缺點,如生成的隨機數(shù)序列的可預測性和低質量
到此這篇關于C++中獲取隨機數(shù)的常用方法小結的文章就介紹到這了,更多相關 C++獲取隨機數(shù)內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
基于WTL 雙緩沖(double buffer)繪圖的分析詳解
本篇文章是對WTL下使用雙緩沖(double buffer)繪圖進行了詳細的分析介紹,需要的朋友參考下2013-05-05