c++11 隨機數random


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;
}

生成的隨機數結果:

12

在例子中,隨機數類是定義在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;
}

設置新的種子后結果如下:

12

在結果可以看出,生成隨機數序列不同了。在這里范圍還是一樣的,那么怎么去改變生成的范圍呢?這時就可以使用隨機數分布類了。

 

#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;
}

結果如下:

12

這里要注意的這個序列也是每次運行程序相同的,因為分布對象將隨機數引擎作為它的參數,分布對象使用它的引擎參數生成隨機數,並將其映射到指定的分布。

---------------------------------------------------------------------------------------------------------------------------------------

現在,讓我更深入一點吧,在圖形上很多時候都要使用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;
}

結果:

12

在這里分布類改變了類型,采用的是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;
}

結果:

12

 更多資料可看:C++Primer 5th

或者 :http://www.cplusplus.com/reference/random/?kw=random


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM