2013年5月17日 星期五

C++ 取亂數 rand()

  • stdlib.h 定義一個常數 RAND_MAX,RAND_MAX 一般是 32767
  • rand() 會回傳 0 ~ 32767 間的一個整數,假設為 r,則 0 <= r <= 32767
  • 避免每次 rand() 回傳的整數都一樣,可用 srand() 設定不同的亂數種子
    例如
    srand(time(NULL));
    int r = rand();
    
  • 利用取餘數的方法,取 0~5 之間的亂數
    int r = rand()%6;
    
  • 利用取餘數,再統一加值的方法,取 2~7 之間的亂數
    int r = rand()%6;
    r = r+2; //統一加2
    
  • 當要取的亂數範圍很大時,每個數出現的機率可能差很多。
    例如取 0 ~ 19999 之間的亂數,(RAND_MAX = 32767)
    rand()%2000=10000 的可能性有 10000、2000
    rand()%2000=15000 的可能性有 15000
    =>出現 10000 的機率 是 15000 的兩倍。
    解決方式:
    // 假設取 0~n-1 之間的亂數,共 n 個數
    // 將可能出現的數字,分成 n 桶,
    // 則每一桶可以裝 bucket (取整數) 個數字 
    int bucket = RAND_MAX / n;
    
    do {
      r = rand() / bucket; // 計算產生的亂數,可裝滿幾桶 (r 桶)
    } while (r >= n);//若可裝滿的桶數比 n 桶大,表示超出範圍,丟棄
    
    /*
    假設 RAND_MAX = 15
    取 0~3 間的亂數, n=4
    int bucket=15/4=3
    屬於第 0 桶的亂數:0、1、2   --->亂數 0
    屬於第 1 桶的亂數:3、4、5   --->亂數 1
    屬於第 2 桶的亂數:6、7、8   --->亂數 2
    屬於第 3 桶的亂數:9、10、11 --->亂數 3
    */
    
  • 取小數亂數
    http://stackoverflow.com/questions/2704521/generate-random-double-numbers-in-c
    double fRand(double fMin, double fMax)
    {
        double f = (double)rand() / RAND_MAX;
        return fMin + f * (fMax - fMin);
    }
    

沒有留言:

張貼留言