c++11提供的<random>實現了隨機數庫,它通過隨機數引擎類(random_number_engines)產生隨機數序列,隨機數分布類(random-number distribution)使用隨機數引擎生成服從特定概率分布的隨機數。
讓我們看一個簡單的例子:
#include <iostream>
#include <random>
using std::cout; using std::endl;
using std::default_random_engine;
int main()
{
default_random_engine e;
for (size_t i = 0; i < 10; ++i) //生成十個隨機數
cout << e() << endl;
cout << "Min random:" << e.min() << endl; //輸出該隨機數引擎序列的范圍
cout << "Max random:" << e.max() << endl;
return 0;
}
生成的隨機數結果:
在例子中,隨機數類是定義在std命名空間的,所以要聲明。隨機數引擎是函數對象,這就是為什么使用e()去生成隨機數。程序每次運行都會生成相同的隨機數序列,這在一定程度有利於程序的調試,但我們有時需要每一次運行產生的隨機數序列都是不同的。我們可以通過設置隨機數引擎的種子來改變引擎的狀態,沒有改變時是使用默認的隨機數種子,這就是為什么每一次都生成同樣的隨機數序列。從結果我們可以知道,默認的種子生成隨機數范圍在1-2147483646之間。
#include <iostream> #include <random> using std::cout; using std::endl; using std::default_random_engine; int main() { default_random_engine e; //或者直接在這里改變種子 e(10) e.seed(10); //設置新的種子 for (size_t i = 0; i < 10; ++i) cout << e() << endl; cout << "Min random:" << e.min() << endl; cout << "Max random:" << e.max() << endl; return 0; }
設置新的種子后結果如下:
在結果可以看出,生成隨機數序列不同了。在這里范圍還是一樣的,那么怎么去改變生成的范圍呢?這時就可以使用隨機數分布類了。
#include <iostream> #include <random> using std::cout; using std::endl; using std::default_random_engine; using std::uniform_int_distribution; int main() { default_random_engine e; uniform_int_distribution<unsigned> u(0, 9); //隨機數分布對象 for (size_t i = 0; i < 10; ++i) //生成范圍為0-9的隨機數序列 cout << u(e) << " "; cout << endl; return 0; }
結果如下:
這里要注意的這個序列也是每次運行程序相同的,因為分布對象將隨機數引擎作為它的參數,分布對象使用它的引擎參數生成隨機數,並將其映射到指定的分布。
---------------------------------------------------------------------------------------------------------------------------------------
現在,讓我更深入一點吧,在圖形上很多時候都要使用0.0-1.0的值(顏色)作為數據,那么怎么生成這樣的序列呢?跟剛才那樣,我們可以使用分布區定義范圍。
#include <iostream> #include <random> using std::cout; using std::endl; using std::default_random_engine; using std::uniform_real_distribution; int main() { default_random_engine e; uniform_real_distribution<double> u(0, 1); //隨機數分布對象 for (size_t i = 0; i < 5; ++i) //生成范圍為0.0-1.0的隨機數序列 cout << u(e) << " "; cout << endl; return 0; }
結果:
在這里分布類改變了類型,采用的是real實數類型的分布類,實例化為<double>,生成0.0-1.0的double隨機數序列。如果你想要獲得分布類范圍的端點,只要簡單的成員函數min()和max()就可以了。
隨機數的重要性質是隨機分布,但是我們也可以生產非均勻分布的隨機數序列。
下面的例子生成符合正態分布的隨機數序列:
#include <iostream> #include <random> #include <vector> #include <string> using std::cout; using std::endl; using std::default_random_engine; using std::normal_distribution; using std::vector; using std::string; int main() { default_random_engine e; vector<unsigned> vals(9); normal_distribution<> n(4, 1.5); //正態分布,大部分生成的隨機數落在0-8之間 for (size_t i = 0; i != 200; ++i) { unsigned v = lround(n(e)); //舍入到最近整數 if (v < vals.size()) ++vals[v]; //統計0-8數字出現的次數 } for (decltype(vals.size()) i = 0; i != vals.size(); ++i) cout << i << ": " << string(vals[i], '#') << endl; return 0; }
結果:
更多資料可看:C++Primer 5th
或者 :http://www.cplusplus.com/reference/random/?kw=random