C語言隨機數小結


C語言中可以使用rand()函數來生成一個從0到RAND_MAX的uniform分布。基於這個函數,我們可以構造出一些特定的隨機數生成器來滿足我們的需求。

(一)0到1的uniform分布:

//generate a random number in the range of [0,1]
double uniform_zero_to_one(){
    return (double)rand()/RAND_MAX;
}

(二)任意實數區間的uniform分布:

//generate a random real number in [start,end]
double uniform_real(double start,double end){
    double rate=(double)rand()/RAND_MAX;
    return start+(end-start)*rate;
}

(三)任意整數區間的uniform分布:

//generate a random integer number in [start,end)
int uniform_integer(int start,int end){
    int base=rand();
    if(base==RAND_MAX)
        return uniform_integer(start,end);
    int range=end-start;
    int remainder=RAND_MAX%range;
    int bucket=RAND_MAX/range;
    if(base<RAND_MAX-remainder)
        return start+base/bucket;
    else
        return uniform_integer(start,end);


}

這個函數要特別說明一下,平常時候我們都是用rand()%n來生成0到n-1的隨機數,但是按這種方法生成的分布並不是uniform的,更詳細的討論可以參見stackoverflow http://stackoverflow.com/questions/2509679/how-to-generate-a-random-number-from-within-a-range-c。另外,我這個函數也是從stackoverflow上獲得,不敢據為己有,此處只為和大家分享。

另外由於RAND_MAX只有32767,因此要生成比這個數更大的隨機數需要另外想辦法,理論上可以直接用0到1的uniform分布直接放縮,但實際效果不好。這里給出一種移位方式的實現。

(四)32bits的隨機數

//generate a random 32 bits integer number 
int rand32(){
    return ((rand()<<16)+(rand()<<1)+rand()%2);
}

有了32bits的隨機數生成方法,就可以構造32bits范圍內的隨機整數區間了,方法和之前16bits的情況一樣。

(五)32bits范圍內的隨機整數區間

//generate a random 32bits integer number in [start,end)
 int uniform_integer_32(int start,int end){
     int base=rand32();
    if(base==RAND32_MAX)
        return uniform_integer_32(start,end);
    int range=end-start;
    int remainder=RAND32_MAX%range;
    int bucket=RAND32_MAX/range;
    if(base<RAND32_MAX-remainder)
        return start+base/bucket;
    else
        return uniform_integer_32(start,end);
}

這里RAND32_MAX定義為0x7fffffff。

除此之外,利用rand()函數構造任意分布的隨機數也是個值得探討的問題。

理論上可以通過(0,1)的uniform分布,加上標准采樣方法(sampling)獲得。但是實現還是不那么容易的。之前在CSDN上看到有人推薦Intel MKL庫(Intel MKL Vector Statistical Library (VSL) is a collection of 9 random number generators and 22 probability distributions that deliver significant performance improvements in physics, chemistry, and financial analysis.)這個庫包括了常見的隨機數生成器,以及可以生成常見的隨機數分布。

偽隨機數其實是一個很值得研究的課題,這里只是拋磚引玉,歡迎討論,歡迎提出更好的方法。

續一:在本文發布后,有人提出來boost庫有關於隨機數的東西,我查了一下,確實如此。這里給出boost庫隨機數文檔的鏈接:http://www.boost.org/doc/libs/1_35_0/libs/random/index.html

續二:C++ 11開始標准庫也自帶了隨機數的函數,詳細請參見相關文檔:http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution


免責聲明!

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



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