亂數有些議題特別拉出來再次討論,不熟的話 可看這篇

1.  [low, up]

假定產生 [10,20] 之整數亂數,先考慮以下程式碼

int( (double)(up-low)*rand()/RAND_MAX+low)

rand() 範圍為 0~RAND_MAX,要產生 up 之情況只有一種:rand() 必須等於 RAND_MAX,無疑不是個均勻之亂數

------

考慮使用四捨五入之方式

int( (double)(up-low)*rand()/RAND_MAX+low+0.5)

若  (double)(up-low)*rand()/RAND_MAX+low

計算結果為 [10.0,10.5) --> 10
計算結果為 [10.5, 11.5) -->11
...
計算結果為 [19.5, 20) ---> 20

頭尾都不平均。

 --------

目前我採用的,欲產生 [low, up] 整數亂數,實際上是產生 [low, up+1) 之整數亂數

int( (double)(up-low+1)*rand()/(RAND_MAX+1)+low)

算式是複雜了點,但認為這麼寫或許可得到「較佳」之效果。

 --------

2. 不重覆亂數

Kunth shuffle 大致如下

void KunthShuffle(int *array, int n)
{
     for(int i=0; i!=n; ++i) array[i] = i;
     for(int i=n-1; i>0; --i){
          j=rand_between(0, i); /* j = [0,i] */
         swap(array[i], array[j]);
    }
}

認為有些場合用不到。如 GA 在隨機挑選二支不同染色體時,直接暴力做即可。

c1 = rand_between(0, population_cnt-1);
do{ c2 = rand_between(0, population_cnt-1); }while(c1==c2);

在一些場合下,或許用亂數跟著排序就好

void SortShuffle(int *array, int n)
{
    int *rnd = new int[n];
    for(int i=0; i!=n; ++i) array[i] = i;
    for(int i=0; i!=n; ++i) rnd[i] = rand(); /* 可和上個 loop 併一起 */
    Sort(array, rnd, n); /* 以 rnd 當 key, 交配時 rnd/array 一起換 */
    delete [] rnd;
}

 --------

建議,Visual Studio 系列,先安裝 SP1 (非英文版 IDE) 或 Feture Pack (英文版 IDE) 回來玩玩,

tr1 裡面有很多寫好的東西,不需再造輪子 (是否有 bug 倒是待測 ),像是 #include <random>,

可先玩玩 tr1::mt19937,為 mersenne twister 之改良。

edisonx 發表在 痞客邦 PIXNET 留言(0) 人氣()