亂數原型 #include <stdlib.h> int rand(void); //取得亂數 void srand(unsigned seed); //設定亂數種子 【亂數的概念】 1.假設有一組數列為 0、1、2、...、9。 2.假設種子為 8。 3.電腦程式啟動執行時,第一次叫用此數列的數字為種子加 7,並除以10取餘數。因此第一次數字為 (8+7)%10=5。 4.第二次叫用時,以第一次數字加 7,並除以10取餘數。 因此第二次數字為 (5+7)%10=2。 5.爾後每次叫用數字時以上列規則執行,則新的數列變成5、2、9、6、3、0、7、4、1、8 (以下循環),感覺上數字順序就被打亂了,因此稱為亂數數列。 6.好的亂數演算法,不會讓使用者看出每一個數字演變的規則,也不容易看出循環規則。 7.為了讓亂數每次起點可以改變,使用者可以定義種子。 以上為例:若改變種子為 4,則亂數數列變成: (4+7)%10=1、(1+7)%10=8、5、2、9、6、3、0、7、4。 8.為了讓亂數可以限制數字範圍,使用者可以將亂數數列除以某一母數取餘數得到新的亂數數列。 以上為例:若定義母數為 6,則原亂數數列為 5、2、9、6、3、0、7、4、1、8,會變成 5%6=5、2%6=2、9%6=3、6%6=0、3%6=3、0%6=0、7%6=1、4%6=4、1%6=1、8%6=2 (以下循環)。 【亂數實驗】 #include <stdio.h> #include <stdlib.h> void main() { int a,i; for(i=0;i<10;i++){ a=rand()%10; printf("%d\n", a); } } 1.請複製上面程式,並執行它,且觀察數字變化。 2.多執行幾次,並觀察數字出現順序是否改變。 3.將程式 a=rand()%10; 改成 a=rand()%6; 並觀察數字變化。 將程式適當修改成如下: #include <stdio.h> #include <stdlib.h> void main() { int a,i; srand(5); for(i=0;i<10;i++){ a=rand()%10; printf("%d\n", a); } } 1.多執行幾次,並觀察數字出現順序是否改變。 2.將 srand(5); 改成 srand(6);,且多執行幾次,並觀察數字出現順序是否改變。 將程式再適當修改成如下: #include <stdio.h> #include <stdlib.h> #include <time.h> void main() { int a,i; srand(time(NULL)); for(i=0;i<10;i++){ a=rand()%10; printf("%d\n", a); } } 多執行幾次,並觀察數字出現順序是否改變。 【說明】 time 原型如下: time_t time(time_t *timer); //取得系統目前秒數。 當指標指向 NULL 時,time 會傳回電腦目前的秒數。 【亂數範圍與起點設定】 1.假設起點為 s,範圍為 r,間隔為 w,則亂數公式為: (rand()%r)*w+s 範例: 亂數數列為 7、10、13、16、19 (共 5 個) 由上數列可知 起點為 7,間隔 3 (10-7),範圍 5 則程式碼為 (rand()%5)*3+7 若間隔無規則可言,則必須使用陣列存取。 範例: 亂數數列為 7、22、19、-100、3、29 (共 6 個) 則程式碼為: int x[]={7, 22, 19, -100, 3, 29}; int y; y=x[(rand()%6]; 【亂數命中機率分配設定】 假設 某亂數數列及機率分配如下:
由上可知最大範圍為 1000 每個數字依照 1000 個配置數量如下:
程式碼 y=rand()%1000; //產生數字 0 至 999 if(y==0) printf("1\n"); else if((y>=1)&&(y<=70)) printf("2\n"); else if((y>=71)&&(y<=370)) printf("3\n"); else printf("4\n"); |