/* 隨機數引擎: * 有狀態的隨機數發生器,生成在預約義的最大小值之間的隨機數 * 不是真正的隨機數--僞隨機 */ int main () { std::default_random_engine eng; cout << "Min: " << eng.min() << endl; cout << "Max: " << eng.max() << endl; cout << eng() << endl; // 生成一個隨機數 cout << eng() << endl; // 生成第二個隨機數 std::stringstream state; state << eng; // 保存引擎狀態 cout << eng() << endl; // 生成一個隨機數 cout << eng() << endl; // 生成第二個隨機數 state >> eng; // 恢復引擎狀態 cout << eng() << endl; // 生成一個隨機數,跟前面的值如出一轍 cout << eng() << endl; // 生成第二個隨機數,跟前面的值如出一轍 } /* 更多例子 */ void printRandom(std::default_random_engine e) { for (int i=0; i<10; i++) cout << e() << " "; cout << endl; } template <typename T> void printArray(T arr) { for (auto v:arr) { cout << v << " "; } cout << endl; } int main () { std::default_random_engine eng; printRandom(eng); std::default_random_engine eng2; printRandom(eng2); //值跟前面徹底同樣,因此引入種子 unsigned seed = std::chrono::steady_clock::now().time_since_epoch().count(); std::default_random_engine e3(seed); // printRandom(e3); eng.seed(); // 重置引擎爲初始狀態 eng.seed(109); // 依據種子109設置引擎狀態 eng2.seed(109); if (eng == eng2) // 兩個引擎狀態相同就相同 cout << "eng and eng2 have the same state" << endl; cout << "\n\n Shuffling:" << endl; int arr[] = {1,2,3,4,5,6,7,8,9}; vector<int> d(arr, arr+9); printArray(d); vector<int> d = {1,2,3,4,5,6,7,8,9}; std::shuffle(d.begin(), d.end(), std::default_random_engine()); printArray(d); std::shuffle(d.begin(), d.end(), std::default_random_engine()); // 相同順序 printArray(d); std::shuffle(d.begin(), d.end(), eng); printArray(d); std::shuffle(d.begin(), d.end(), eng); // 不一樣順序 printArray(d); } /* 其餘隨機數引擎 參看cplusplus.com*/ /* 隨機數分佈 */ // 默認的引擎都是均勻分佈,且取值範圍固定 int main () { // 引擎只是提供了一個隨機源 unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); std::default_random_engine e(seed); // 如何獲取一個0到5之間的隨機數? // e()%6 // -- 隨機性差 // -- 只能均勻分佈 std::uniform_int_distribution<int> distr(0,5); // range: [0,5] -- 0和5都包含,這個惟一一個全閉區間的特例 // 默認參數: [0, INT_MAX] cout << " int_distribution: " << endl; for (int i=0; i<30; i++) { cout << distr(e) << " "; } cout << "\n\n real_distribution: " << endl; std::uniform_real_distribution<double> distrReal(0,5); // 半開區間: [1, 5) // default param: [0, 1) for (int i=0; i<30; i++) { cout << distrReal(e) << " "; } cout << " poisson_distribution: " << endl; std::poisson_distribution<int> distrP(1.0); // mean (double) for (int i=0; i<30; i++) { cout << distrP(e) << " "; } cout << endl; cout << " normal_distribution: " << endl; std::normal_distribution<double> distrN(10.0, 3.0); // 平均值和標準差 vector<int> v(20); for (int i=0; i<800; i++) { int num = distrN(e); // convert double to int if (num >= 0 && num < 20) v[num]++; // v[num] 記錄數字num出現的次數 } for (int i=0; i<20; i++) { cout << i << ": " << std::string(v[i], '*') << endl; } cout << endl; // Stop using rand()%n; } /* 其餘分佈參看cplusplus.com*/