C/C++ 使用rand 函數產生隨機亂數教學與範例程式碼- G. T. Wang
文章推薦指數: 80 %
固定亂數種子. 由於電腦實際上並沒有辦法自己產生「真正的亂數」,只能透過複雜的數學演算法模擬出類似亂 ...
Blogger舊站
關於
Facebook
Flickr
物聯網
網站架設
程式設計
統計
素食
特價優惠
宗教
物聯網
網站架設
程式設計
統計
素食
特價優惠
宗教
C/C++使用rand函數產生隨機亂數教學與範例程式碼
2017/04/06
0則留言
本篇介紹C/C++中使用rand函數產生亂數的方法,並且提供各種常用的範例程式碼。
在撰寫C/C++程式時,如果需要產生一些簡單的亂數,最方便的作法就是使用rand這個亂數產生函數,以下介紹這個函數的相關用法與範例。
rand只能提供基本的亂數,如果您需要更進階的功能或是品質比較好的亂數,建議改用C++的
基本亂數產生方法
C語言中若要產生亂數,可以使用stdlib.h中的rand函數,而在呼叫rand函數之前,要先使用srand函數設定初始的亂數種子:
#include
printf("RAND_MAX=%d\n",RAND_MAX);
在C++中的亂數產生方式也跟C幾乎相同,只是標頭檔換一下而已:
#include
最常用到固定亂數種子的時機可能就是除錯或是驗證演算法是否有錯誤的時候,如果沒有固定亂數種子的話,每次跑出來的結果都不同,會讓除錯的難度提高。
[0,1)浮點數亂數
若要產生0到1之間的浮點數亂數,可以這樣寫:
#include
特定範圍浮點數亂數
若要產生特定範圍的浮點數亂數,可以這樣寫:
#include
特定範圍整數亂數
若想要產生特定範圍的整數亂數,可以這樣寫:
#include
上面這種使用餘數運算(%)的方式只是比較方便的寫法,事實上使用餘數運算所產生的整數亂數在理論上不是標準的均勻分布,我們以一個簡單的例子來解釋,假設RAND_MAX的值為10,而我們要產生介於3到5之間的整數亂數(亦即min=3、max=5),以下是所有的可能性對照表:
轉換後的整數亂數
rand函數產生的亂數
出現機率
3
0、3、6、9
4/11
4
1、4、7、10
4/11
5
2、5、8
3/11
rand函數所產生的每一個整數其出現的機率是均等的,但是經過於數運算的轉換之後,因為RAND_MAX通常不會被整除,所以轉換之後的整數亂數出現機率就存在有細微的偏差,以這個例子來說,3、4、5三個數字出現的機率比是4:4:3。
另外有些人會先產生固定範圍的浮點數亂數,再將浮點數轉型為整數,例如產生[3,6)的浮點數亂數,然後轉型為[3,5]的整數亂數,其實這種方式跟餘數運算一樣會有每個整數出現機率不均等的問題,簡單來說就是現在有11個球要放進3個籃子裡,不管怎麼放,每個籃子的球都不可能一樣多。
如果您需要非常標準的均勻分布(uniformdistribution),可以使用這個版本:
/*產生[0,n)均勻分布的整數亂數*/
intrandint(intn){
if((n-1)==RAND_MAX){
returnrand();
}else{
/*計算可以被整除的長度*/
longend=RAND_MAX/n;
assert(end>0L);
end*=n;
/*將尾端會造成偏差的幾個亂數去除,
若產生的亂數超過limit,則將其捨去*/
intr;
while((r=rand())>=end);
returnr%n;
}
}
使用這個randint函數產生特定範圍整數亂數:
/*指定亂數範圍*/
intmin=4;
intmax=10;
/*產生[min,max]的整數亂數*/
intx=randint(max-min+1)+min;
這種作法就好像要把11個球要放進3個籃子裡,而最後多出來的2顆球就直接丟掉,確保每個籃子都一樣只有3顆,這樣大家的機率就可以相等了。
這種使用截斷分布(truncateddistribution)來校正機率的方式雖然在理論上是正確的,但是rand函數是使用LCG(LinearCongruentialGenerator)來產生亂數的,他的優點只是快速、方便而已,但它本身所產生的亂數品質沒有非常好,再怎麼校正效果都有限,若需要高品質的亂數,請改用C++11標準的
參考資料:Edison.X.Blog、tutorialspoint、StackOverflow、StackOverflow
程式設計
C/C++
G.T.Wang
個人使用Linux經驗長達十餘年,樂於分享各種自由軟體技術與實作文章。
LeaveaReply取消回覆
留言*
Name*
Email*
Website
搜尋
分類Arduino(5)
BeagleBoneBlack(1)
DIY(54)
Linux(317)
macOS(33)
Octave(15)
Perl(12)
R(47)
Windows(98)
WordPress(16)
個人(15)
免費(35)
兒童(30)
實用工具(85)
手機(13)
技巧(45)
有趣(99)
樹莓派(57)
物聯網(55)
玄學(11)
生活(209)
程式設計(137)
統計學(8)
網頁空間(36)
網頁開發(128)
虛擬化(7)
農業(42)
遊戲(9)
開箱(132)
雲端(4)
宗教
如何戒邪淫、遠離婚外情
戒淫寶典:《壽康寶鑑》白話有聲書
公益
台灣世界展望會
Yahoo奇摩公益
igiving公益網
家扶基金會
社團法人新竹縣愛心物資集發協會
©2022G.T.Wang
延伸文章資訊
- 1你的程式夠「亂」嗎? | iThome
亂數的產生雖然是不起眼的小函式,有機會的話可以探索一下,因為, ... 而在API文件會指出,rand()預設的亂數種子是0,可使用srand()來設定亂數種子, ...
- 2亂數
亂數Random Number · 亂數的產生,都必須依一定的種子產生,在BASIC中則是借用RANDOMIZE敘述。 · RANDOMIZE n:n為亂數種子,其範圍介於(-32768-327...
- 3動滋券中獎亂數種子出爐今等好康簡訊也可上網查 - 蘋果日報
- 4偽隨機性- 維基百科,自由的百科全書 - Wikipedia
偽隨機性(英語:Pseudorandomness)是一個過程似乎是隨機的,但實際上並不是。例如偽亂數是使用一個確定性的演算法計算出來的似乎是隨機的數序,因此偽亂數實際上並不 ...
- 5C/C++ 使用rand 函數產生隨機亂數教學與範例程式碼- G. T. Wang
固定亂數種子. 由於電腦實際上並沒有辦法自己產生「真正的亂數」,只能透過複雜的數學演算法模擬出類似亂 ...