天天看點

随機函數與機率設定

一、random函數不是ansi c标準,不能在gcc,vc等編譯器下編譯通過。 可改用c++下的rand函數來實作。

     1、c++标準函數庫提供一随機數生成器rand,傳回0-rand_max之間均勻分布的僞随機整數。 rand_max必須至少為32767。rand()函數不接受參數,預設以1為種子(即起始值)。 随機數生成器總是以相同的種子開始,是以形成的僞随機數列也相同,失去了随機意義。(但這樣便于程式調試) 

     2、c++中另一函數srand(),可以指定不同的數(無符号整數變元)為種子。但是如果種子相同,僞随機數列也相同。一個辦法是讓使用者輸入種子,但是仍然不理想。 

     3、 比較理想的是用變化的數,比如時間來作為随機數生成器的種子。 time的值每時每刻都不同。是以種子不同,是以,産生的随機數也不同。

二、rand()的用法   

     rand()不需要參數,它會傳回一個從0到最大随機數的任意整數,最大随機數的大小通常是固定的一個大整數。 這樣,如果你要産生0~10的10個整數,可以表達為: 

  int n = rand() % 11; 

     這樣,n的值就是一個0~10的随機數,如果要産生1~10,則是這樣: 

  int n = 1 + rand() % 10; 

  總結來說,可以表示為: 

  a + rand() % n 

     其中的a是起始值,n是整數的範圍。 若要0~1的小數,則可以先取得0~10的整數,然後均除以10即可得到随機到十分位的10個随機小數,若要得到随機到百分位的随機小數,則需要先得到0~100的10個整數,然後均除以100,其它情況依

此類推。 

     通常rand()産生的随機數在每次運作的時候都是與上一次相同的,這是有意這樣設計的,是為了便于程式的調試。若要産生每次不同的随機數,可以使用srand( seed )函數進行随機化,随着seed的不同,就能夠産生不同的随機數。 

     如大家所說,還可以包含time.h頭檔案,然後使用srand(time(0))來使用目前時間使随機數發生器随機化,這樣就可以保證每兩次運作時可以得到不同的随機數序列(隻要兩次運作的間隔超過1秒)。

注:rand()産生的是0 to rand_max (32767)上的随機數,而32767不能被11整除。

是以 int n = rand() % 11; 得到的随機數,并不是從0-10一緻分布的取9,10的機率取0-8幾個數字的機率少了11/32767約為1/2978;

是以要取0~m的随機數,若m較小時這樣作問題不大,但m較大時,例如m=30000,則取到0-2767的機率是取後面幾個數字的兩倍,嚴重不符合随機分布! 

三、按要求設定機率

比如要設定一個10%的機率問題,我們可以采取rand()函數來實作,在if條件句判斷裡,用rand()得到的值%一個設定的值,再與另一個值做“==”運算。 例如:

 

四、計算機的僞随機數是由随機種子根據一定的計算方法計算出來的數值。是以,隻要計算方法一定,随機種子一定,那麼産生的随機數就是固定的。

       隻要使用者或第三方不設定随機種子,那麼在預設情況下随機種子值為1,來自系統時鐘。

1、要取得[a,b)的随機整數,使用(rand() % (b-a))+ a (結果值含a不含b)。
2、要取得[a,b]的随機整數,使用(rand() % (b-a+1))+ a (結果值含a和b)。
3、要取得(a,b]的随機整數,使用(rand() % (b-a))+ a + 1 (結果值不含a含b)。
4、即(通用公式:a + rand() % n;取得[a,a+n) 的随機整數,其中的a是起始值,n是整數的範圍。)
5、要取得[a,b) 的随機整數,另一種表示:a + (int)(b-a) * rand() / (rand_max + 1)。
6、要取得[a,b] 的随機整數 另一種表示:a + (int)(b-a) * rand() / (rand_max )。
7、要取得[0,1] 之間的浮點數 ,可以使用rand() / double(rand_max)。

繼續閱讀