一、概述
C++中的random庫提供了一種方便的生成隨機數的方法。隨機數可以應用於很多領域,比如博弈、密碼學、計算機圖形學等。C++ Random的優勢主要在於其靈活性和高效性。Random庫允許用戶控制生成的隨機數範圍、分布和種子,從而滿足不同領域的需求。下面將從多個方面對Random庫進行詳細的闡述。
二、Random庫使用方法
C++ Random庫是C++11標準引入的新特性,它提供了各種產生隨機數的方法。這裡我們介紹一下最基本的生成隨機整數和浮點數的方法。
1. 生成隨機整數
#include #include using namespace std; int main() { // 默認構造函數使用隨機設備為種子生成隨機數 default_random_engine random(time(NULL)); uniform_int_distribution uid(0, 9); for (int i = 0; i < 10; i++) { int num = uid(random); cout << num << endl; } return 0; }
代碼解釋:
首先我們使用默認構造函數構造隨機設備,將當前時間做為種子生成隨機數。Uniform_int_distribution用來定義生成隨機整數的範圍為0~9。隨後在循環中不斷調用uid和random來獲取隨機整數。這樣我們就可以得到一個隨機整數的序列。
2. 生成隨機浮點數
生成隨機浮點數就需要使用uniform_real_distribution類了,代碼如下:
#include #include using namespace std; int main() { default_random_engine random(time(NULL)); uniform_real_distribution uid(0.0, 1.0); for (int i = 0; i < 10; i++) { float num = uid(random); cout << num << endl; } return 0; }
代碼解釋:
這段代碼與生成隨機整數的代碼很相似。唯一不同的地方是我們使用了uniform_real_distribution類來生成隨機浮點數。同樣的,我們可以使用random和uid來獲取浮點數的序列。
三、Random庫進階應用
1. 控制種子
在Random庫中,我們可以通過改變隨機數生成器的種子來控制隨機序列的生成。Seed_seq是一個用來生成隨機數種子序列的類,並可以控制隨機數序列的生成。下面是一個關於控制種子的例子:
#include #include using namespace std; int main() { int seed[3] = {1, 2, 3}; seed_seq sseq(seed, seed + 3); mt19937 gen(sseq); uniform_int_distribution uid(0, 10); for (int i = 0; i < 10; i++) { int num = uid(gen); cout << num << endl; } return 0; }
代碼解釋:
首先我們定義一個長度為3的int數組seed,並將其作為參數傳給seed_seq類。seed_seq類的構造函數將seed數組中的值轉化為均勻分布在32位整數空間內的隨機數種子序列,並將其存儲在一定的緩存中。用戶可以通過傳遞緩存來控制自己的隨機數生成序列。由於mt19937引擎和默認引擎一樣,也接受整數種子,所以我們直接將隨機數種子序列傳遞給mt19937對象,並使用uid隨機分布來隨機數,輸出結果。
2. 修改隨機數分布
Random庫的隨機數分布類有:uniform_int_distribution、uniform_real_distribution、normal_distribution、chi_squared_distribution、cauchy_distribution和gamma_distribution等。不同的分布定義了不同的隨機數生成規律。下面是一個改變隨機分布的例子:
#include #include using namespace std; int main() { default_random_engine random(time(NULL)); normal_distribution nd(5.0, 1.5); for (int i = 0; i < 10; i++) { double num = nd(random); cout << num << endl; } return 0; }
代碼解釋:
這段代碼與前面的隨機整數和浮點數的生成代碼非常相似。這個例子中我們使用normal_distribution來定義正態分布,其參數分別為均值和標準差。均值越大,所得到的隨機數分布中心越靠後,而標準差越大,則隨機數分布的幅度越寬廣。
3. 生成隨機數類
如果我們需要在大量代碼中使用隨機數,每次都寫一遍隨機數生成代碼可能會比較冗餘。實際上,Random庫提供了一個方便的生成隨機數類,可以簡化我們的代碼量。下面是一個使用生成隨機數類的例子:
#include #include using namespace std; class RandomNumberGenerator { private: mt19937 generator; public: RandomNumberGenerator() { std::random_device rd; generator.seed(rd()); } int getRandomInt(int min, int max) { std::uniform_int_distribution dist(min, max); return dist(generator); } float getRandomFloat(float min, float max) { std::uniform_real_distribution dist(min, max); return dist(generator); } }; int main() { RandomNumberGenerator rng; for (int i = 0; i < 10; i++) { int num = rng.getRandomInt(0, 10); float fnum = rng.getRandomFloat(0.0, 1.0); cout << num << "," << fnum << endl; } return 0; }
代碼解釋:
這個例子中,我們定義了RandomNumberGenerator類,通過類的實例化來使用隨機數生成器。類構造函數中我們使用std::random_device產生隨機設備,而不是用當前時間做為種子。RandomNumberGenerator類定義了getRandomInt和getRandomFloat成員函數來生成隨機整數和隨機浮點數。注意到,我們在成員函數中也是用uniform_int_distribution和uniform_real_distribution來定義隨機數的範圍,使用了函數模板來允許指定不同的類型。
4. 並行生成隨機數
為了提高隨機數的生成效率,Random庫提供了一個並行生成隨機數的方法,從而快速生成一定規模的隨機數序列。parallel_random_device方法用於生成一個並行隨機設備,它保證多線程訪問該設備不會互相干擾。下面是一個並行生成隨機數的例子:
#include #include #include using namespace std; int main() { std::vector nums(10000); std::independent_bits_engine e; std::generate(nums.begin(), nums.end(), std::bind(e)); for (int i = 0; i < 10000; i += 100) { cout << nums[i] << endl; std::this_thread::sleep_for(std::chrono::duration(100)); } return 0; }
代碼解釋:
這個例子中我們使用independent_bits_engine方法來生成一個獨立的顆粒生成隨機數的設備。該函數的模板參數包括:隨機數引擎類型、生成的隨機數位數、隨機數種子類型。我們使用std::default_random_engine作為隨機數引擎類型,CHAR_BIT(即8)作為生成隨機數的位數,unsigned int作為隨機數種子類型。隨後我們生成了一個長度為10000的int數組,並使用std::generate方法和std::bind函數來快速生成10,000個隨機數。在循環中,我們每次輸出數組中的一個元素,並等待100毫秒。
四、總結
總地來講,C++ Random庫提供了各種方便的生成隨機數的方法,適用於博弈、密碼學、計算機圖形學等領域。在使用中需要注意控制隨機數生成器的種子、隨機數分布和並行生成隨機數的使用方法。待需要使用全局共享的隨機數生成時,我們可以使用獨立隨機設備的方式來保證多線程生成的隨機數不會互相干擾。通過Random庫,C++開發工程師可以輕鬆生成隨機數序列,豐富自己的代碼體驗。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/236129.html