C++11帶來諸多特性,random就是其一.
1. random_device
標准庫提供了一個非確定性隨機數生成設備.在Linux的實現中,是讀取/dev/urandom設備;Windows的實現居然是用rand_s,在這里強烈譴責一下.
random_device提供()操作符,用來返回一個min()到max()之間的一個數字.如果是Linux(Unix Like或者Unix)下,都可以使用這個來產生高質量的隨機數,可以理解為真隨機數.
#include <iostream> #include <random> int main() { std::random_device rd; for(int n=0; n<20000; ++n) std::cout << rd() << std::endl; return 0; }
2. random number engine
標准把隨機數抽象成隨機數引擎和分布兩部分.引擎用來產生隨機數,分布產生特定分布的隨機數(比如平均分布,正太分布等).
標准提供三種常用的引擎:linear_congruential_engine,mersenne_twister_engine和subtract_with_carry_engine.第一種是線性同余算法,第二種是梅森旋轉算法,第三種帶進位的線性同余算法.第一種是最常用的,而且速度也是非常快的; 第二種號稱是最好的偽隨機數生成器;第三種沒用過....
隨機數引擎接受一個整形參數當作種子,不提供的話,會使用默認值. 推薦使用random_device來產生一個隨機數當作種子.(windows下愛咋整咋整,誰叫windows的random_device是調用rand_s)
#include <iostream> #include <random> int main() { std::random_device rd; std::mt19937 mt(rd()); for(int n = 0; n < 10; n++) std::cout << mt() << std::endl; return 0; }
3. random number distributions
標准提供各種各樣的分布,不過我們經常用的比較少,比如平均分布,正太分布...使用也很簡單
//平均分布 #include <random> #include <iostream> int main() { std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution<> dis(1, 6); for(int n=0; n<10; ++n) std::cout << dis(gen) << ' '; std::cout << '\n'; }
//正太分布 #include <iostream> #include <iomanip> #include <string> #include <map> #include <random> #include <cmath> int main() { std::random_device rd; std::mt19937 gen(rd()); // values near the mean are the most likely // standard deviation affects the dispersion of generated values from the mean std::normal_distribution<> d(5,2); std::map<int, int> hist; for(int n=0; n<10000; ++n) { ++hist[std::round(d(gen))]; } for(auto p : hist) { std::cout << std::fixed << std::setprecision(1) << std::setw(2) << p.first << ' ' << std::string(p.second/200, '*') << '\n'; } }
參考:
1. http://en.cppreference.com/w/cpp/numeric/random
2. windows下的高質量隨機數生成器,參考CryptGenRandom API, 以及http://www.cnblogs.com/egmkang/archive/2011/03/05/1971586.html