C言語プログラミングにおける乱数生成のための入門チュートリアル
3448 ワード
言語が乱数を生成するのは一般的なプログラミング機能のタスクで、もちろんこれも難しくありません.2、3つの関数を呼び出すと出てきますが、これらの関数が具体的にどのような役割を果たし、どのように乱数を生成しているか知っていますか.
いくつかの概念
乱数:数学的に発生するのはすべて擬似乱数で、本当の乱数は物理的な方法で発生します.
乱数シード:乱数の生成は算術規則によって生成され、srand(seed)の乱数シードは異なり、rand()のランダム数値は異なり、毎回の乱数シードが同じであればrand()の値は同じである.したがって、乱数を生成するには、srand(seed)の乱数シードもランダムでなければならない.
ランダムシードをsrand()で生成する
プロトタイプ:void srand(unsigned int seed);
乱数シードを設定し、乱数シードをランダムにするためにtime(NULL)の値をseedとして使用するのが一般的です.
time()乱数シード用
関数プロトタイプ:time_t time ( time_t * timer );
time()関数は、1970-1-1 00:00:00から現在の時間までの秒数を返します.
使う時はこうです:srand(unsigned(time(NULL)));例えば1~10の間のランダム整数を生成する
上のプログラムではsrandがforループの外にあることに注意し、srandをforループの中に入れると、発生するたびに乱数が同じになります.
rand()で乱数を生成する
プロトタイプ:int rand(void);
作用は1つの乱数を発生するので、もちろん乱数は範囲があって、0~RAND_ですMAX間では,乱数は乱数シードに関係する.具体的には、乱数rand()が呼び出されると、次のように実行されます.
ユーザーがsrand(seed)を呼び出したことがある場合、彼はsrand(seed)を再呼び出して乱数シードを生成します.srand(seed)が呼び出されていないことに気づいたら、srand(1)が自動的に呼び出されます.srand(seed)を呼び出して生成された乱数シードが同じであれば(すなわちseedの値が同じ)、rand()が生成した乱数も同じである.したがって、rand()が呼び出されるたびに生成される値が異なる場合は、srand(seed)が呼び出されるたびに、seedは同じではありません.ここでtime(NULL)を用いて乱数シードを生成することが多い理由である.
C言語ではrand()関数を用いて0からRAND_へMAXのuniform分布.この関数に基づいて,我々のニーズを満たすためにいくつかの特定の乱数生成器を構築することができる.(一)0から1のuniform分布:
(二)任意の実数区間のuniform分布:
(3)任意の整数区間のuniform分布:
この関数は特に,通常rand()%nで0からn−1の乱数を生成するが,この方法で生成される分布はuniformではなくRAND_MAXは32767しかないので、この数よりも大きな乱数を生成するには別の方法が必要で、理論的には0から1のuniform分布で直接縮小することができますが、実際の効果はよくありません.ここでは、シフト方式の実装を示す.
(四)32 bitsの乱数
32 bitsの乱数生成方法があれば,32 bits範囲内のランダム整数区間を構築することができ,方法は前の16 bitsの場合と同様である.
(五)32 bits範囲内のランダム整数区間
ここでRAND 32_MAXは0 x 7 fffffffと定義される.
それ以外にrand()関数を用いて任意分布の乱数を構築することも検討に値する問題である.
理論的には(0,1)のuniform分布に標準サンプリング法(sampling)を加えて得ることができる.
いくつかの概念
乱数:数学的に発生するのはすべて擬似乱数で、本当の乱数は物理的な方法で発生します.
乱数シード:乱数の生成は算術規則によって生成され、srand(seed)の乱数シードは異なり、rand()のランダム数値は異なり、毎回の乱数シードが同じであればrand()の値は同じである.したがって、乱数を生成するには、srand(seed)の乱数シードもランダムでなければならない.
ランダムシードをsrand()で生成する
プロトタイプ:void srand(unsigned int seed);
乱数シードを設定し、乱数シードをランダムにするためにtime(NULL)の値をseedとして使用するのが一般的です.
time()乱数シード用
関数プロトタイプ:time_t time ( time_t * timer );
time()関数は、1970-1-1 00:00:00から現在の時間までの秒数を返します.
使う時はこうです:srand(unsigned(time(NULL)));例えば1~10の間のランダム整数を生成する
#include
#include
int main()
{
srand(time(NULL));
for(int i=0;i < 10;i++)
{
int randValue=rand()%10;
}
}
上のプログラムではsrandがforループの外にあることに注意し、srandをforループの中に入れると、発生するたびに乱数が同じになります.
rand()で乱数を生成する
プロトタイプ:int rand(void);
作用は1つの乱数を発生するので、もちろん乱数は範囲があって、0~RAND_ですMAX間では,乱数は乱数シードに関係する.具体的には、乱数rand()が呼び出されると、次のように実行されます.
ユーザーがsrand(seed)を呼び出したことがある場合、彼はsrand(seed)を再呼び出して乱数シードを生成します.srand(seed)が呼び出されていないことに気づいたら、srand(1)が自動的に呼び出されます.srand(seed)を呼び出して生成された乱数シードが同じであれば(すなわちseedの値が同じ)、rand()が生成した乱数も同じである.したがって、rand()が呼び出されるたびに生成される値が異なる場合は、srand(seed)が呼び出されるたびに、seedは同じではありません.ここでtime(NULL)を用いて乱数シードを生成することが多い理由である.
C言語ではrand()関数を用いて0からRAND_へMAXのuniform分布.この関数に基づいて,我々のニーズを満たすためにいくつかの特定の乱数生成器を構築することができる.(一)0から1のuniform分布:
//generate a random number in the range of [0,1]
double uniform_zero_to_one(){
return (double)rand()/RAND_MAX;
}
(二)任意の実数区間のuniform分布:
//generate a random real number in [start,end]
double uniform_real(double start,double end){
double rate=(double)rand()/RAND_MAX;
return start+(end-start)*rate;
}
(3)任意の整数区間のuniform分布:
//generate a random integer number in [start,end)
int uniform_integer(int start,int end){
int base=rand();
if(base==RAND_MAX)
return uniform_integer(start,end);
int range=end-start;
int remainder=RAND_MAX%range;
int bucket=RAND_MAX/range;
if(base
この関数は特に,通常rand()%nで0からn−1の乱数を生成するが,この方法で生成される分布はuniformではなくRAND_MAXは32767しかないので、この数よりも大きな乱数を生成するには別の方法が必要で、理論的には0から1のuniform分布で直接縮小することができますが、実際の効果はよくありません.ここでは、シフト方式の実装を示す.
(四)32 bitsの乱数
//generate a random 32 bits integer number
int rand32(){
return ((rand()<<16)+(rand()<<1)+rand()%2);
}
32 bitsの乱数生成方法があれば,32 bits範囲内のランダム整数区間を構築することができ,方法は前の16 bitsの場合と同様である.
(五)32 bits範囲内のランダム整数区間
//generate a random 32bits integer number in [start,end)
int uniform_integer_32(int start,int end){
int base=rand32();
if(base==RAND32_MAX)
return uniform_integer_32(start,end);
int range=end-start;
int remainder=RAND32_MAX%range;
int bucket=RAND32_MAX/range;
if(base
ここでRAND 32_MAXは0 x 7 fffffffと定義される.
それ以外にrand()関数を用いて任意分布の乱数を構築することも検討に値する問題である.
理論的には(0,1)のuniform分布に標準サンプリング法(sampling)を加えて得ることができる.