乱数及び確率による乱数の生成
インスタンス1は、単純に乱数を生成します.
この種は翌日に大量の重複データが発生すると,連続的な長時間の応用に合わない.
例2、主に種子の発生を改善する
例3、重複データを生成しないランダムな方法
例4、一定の確率で乱数(確率100%)を生成する
方法例:1 20%2 30%3 50%
20個の1、30個の2、50個の3をランダムに配列に入れ、ランダムに1-100を出して、対応する数字の下に表示された数字を出すことができます.
方法2:
かくりつで区切る
10個の数字1 2は1を表し、3 4 5は3を表し、6 7 8 9 10は数字5を表し、一定の確率のランダムな数字を生成する.
例:
例5は、一定の確率で乱数(非100%)を生成する
コードの例:
乱数が発生しても精巧ではないかもしれませんが
解析結果:
total=999999 1=0.328019% 2=0.127217% 3=0.181625% 4=0.126948% 5=0.23619%
もう一つの考え方があります.
合計:64、ランダム1-64の数、もし34、a+b+c>34であれば、ランダム数は13で、それからcを0にして、和を求めて、再びランダムにして、順番に下ります...ランダムに3つの数値で終了するとします.
例:
単純なシャッフルアルゴリズムを使用して、重複しない乱数を生成します.
5.一定範囲の乱数を生成する汎用表現式は、[a,b)の乱数を取得するには、(rand()%(b-a)))+aを用いる;[a,b]の乱数を取得するには、(rand()%(b-a+1)+aを用いる;(a,b)のランダム整数を取得するには、(rand()%(b-a)+a+1を使用します.汎用式:a+rand()%n;ここで、aは開始値であり、nは整数の範囲である.aからbの間のランダムな整数を取得するには、a+(int)b*rand()/(RAND_MAX+1)を表す.0~1の浮動小数点数を取得するにはrand()/double(RAND_MAX)を使用します.
#include
#include
using namespace std;
int Random(double min, double max);
int main(int argc, char *argv[])
{
srand((int)time(NULL));
int t=0;
for(int i=0;i<10;++i)
{
t = Random(1, 11);
cout << t << " ";
}
cout << endl;
return 0;
}
int Random(double start, double end)
{
return start+(end-start)*rand()/(RAND_MAX + 1.0);
}
この種は翌日に大量の重複データが発生すると,連続的な長時間の応用に合わない.
例2、主に種子の発生を改善する
#include
#include
#include
using namespace std;
int Random(double min, double max);
int main(int argc, char *argv[])
{
unsigned int seedVal;
struct timeb timeBuf;
ftime(&timeBuf);
seedVal=((((unsigned int)timeBuf.time & 0xFFFF)+
(unsigned int)timeBuf.millitm)^
(unsigned int)timeBuf.millitm);
srand((unsigned int)seedVal);
int t=0;
for(int i=0;i<10;++i)
{
t = Random(1, 11);
cout << t << " ";
}
cout << endl;
cout << timeBuf.millitm << " " << ( timeBuf.millitm^timeBuf.millitm) << endl;
return 0;
}
int Random(double start, double end)
{
return start+(end-start)*rand()/(RAND_MAX + 1.0);
}
例3、重複データを生成しないランダムな方法
#include
#include
#include
using namespace std;
int N=100,M=10;
int a[100],b[100];
int Random(double min, double max);
int NorepeatRandom(double start, double end);
int NorepeatRandom2(double start, double end);
int main(int argc, char *argv[])
{
unsigned int seedVal;
struct timeb timeBuf;
ftime(&timeBuf);
seedVal=((((unsigned int)timeBuf.time & 0xFFFF)+
(unsigned int)timeBuf.millitm)^
(unsigned int)timeBuf.millitm);
srand((unsigned int)seedVal);
// NorepeatRandom(0,0);
NorepeatRandom2(0,0);
for(int i=0; i< M;++i)
{
cout << b[i] << " ";
}
cout << endl;
return 0;
}
//repeat random
int Random(double start, double end)
{
return start+(end-start)*rand()/(RAND_MAX + 1.0);
}
//not repeate random
int NorepeatRandom(double start, double end)
{
int i,j,k;
for (i=0;i
例4、一定の確率で乱数(確率100%)を生成する
方法例:1 20%2 30%3 50%
20個の1、30個の2、50個の3をランダムに配列に入れ、ランダムに1-100を出して、対応する数字の下に表示された数字を出すことができます.
方法2:
かくりつで区切る
10個の数字1 2は1を表し、3 4 5は3を表し、6 7 8 9 10は数字5を表し、一定の確率のランダムな数字を生成する.
例:
#include
#include
#include
using namespace std;
int Random(double min, double max);
int main(int argc, char *argv[])
{
unsigned int seedVal;
struct timeb timeBuf;
ftime(&timeBuf);
seedVal=((((unsigned int)timeBuf.time & 0xFFFF)+
(unsigned int)timeBuf.millitm)^
(unsigned int)timeBuf.millitm);
srand((unsigned int)seedVal);
//1 20% 2 30% 3 50%
int i = 0, t;
int n1=0,n2=0,n3=0;
while(++i<100000)
{
t = Random(1, 11);
if(t<=0 || t>10)
break;
switch(t)
{
case 1:
case 2:
++n1;
break;
case 3:
case 4:
case 5:
++n2;
break;
case 6:
case 7:
case 8:
case 9:
case 10:
++n3;
break;
defalt:
break;
}
}
cout << ((double)n1/100000*100) << "% " << ((double)n2/100000*100) << "% "<
例5は、一定の確率で乱数(非100%)を生成する
コードの例:
int a=20,b=7,c=13,d=9,e=15; a 20/64=0.3125 b 7/64=0.1093........
#include
#include
#include
#include
乱数が発生しても精巧ではないかもしれませんが
解析結果:
total=999999 1=0.328019% 2=0.127217% 3=0.181625% 4=0.126948% 5=0.23619%
もう一つの考え方があります.
int a=20,b=7,c=13,d=9,e=15
合計:64、ランダム1-64の数、もし34、a+b+c>34であれば、ランダム数は13で、それからcを0にして、和を求めて、再びランダムにして、順番に下ります...ランダムに3つの数値で終了するとします.
例:
#include
#include
#include
using namespace std;
static int k[6][2];
int a[] = {12, 34, 21, 32, 9, 16}; //
void initdata()
{
srand(time(NULL));
for(int i=0;i<6;++i)
{
k[i][0] += a[i];
}
for(int i=0;i<6;++i)
{
k[i][1] = 0;
}
}
void setarray()
{
for(int i=0;i<6;i++)
{
k[i][1] = 0;
}
}
int getonerand()
{
int tol = 0;
for (int i=0; i<6; i++)
{
if (k[i][1] == 0)
tol = tol + k[i][0];
}
int d = 1+(int)(1.0*tol*rand()/(RAND_MAX+1.0));
int tmpsum = 0;
for(int i=0; i<6; i++)
{
if (k[i][1] == 0)
{
tmpsum = tmpsum + k[i][0];
if (tmpsum >= d)
{
k[i][1] = 1;
return (i);
}
}
}
}
int main(int argc, char *argv[])
{
initdata();
int j=0;
while(j++ < 30)
{
for(int i=0;i<4;++i)
{
int t = getonerand();
cout << a[t] << " ";
}
cout << endl;
setarray();
}
return 0;
}
単純なシャッフルアルゴリズムを使用して、重複しない乱数を生成します.
void shuffle2(int* cards, int n)
{
// i-1 i
for (int i = 0; i < n; i++)
{
int rand = Random2(0, i);
int temp = cards[rand];
cards[rand] = cards[i];
cards[i] = temp;
}
}
int* shuffle(int* cards, int n)
{
if (n <= 0)
return cards;
shuffle(cards, n - 1);
int rand = Random2(0, n);
int temp = cards[rand];
cards[rand] = cards[n];
cards[n] = temp;
return cards;
}
5.一定範囲の乱数を生成する汎用表現式は、[a,b)の乱数を取得するには、(rand()%(b-a)))+aを用いる;[a,b]の乱数を取得するには、(rand()%(b-a+1)+aを用いる;(a,b)のランダム整数を取得するには、(rand()%(b-a)+a+1を使用します.汎用式:a+rand()%n;ここで、aは開始値であり、nは整数の範囲である.aからbの間のランダムな整数を取得するには、a+(int)b*rand()/(RAND_MAX+1)を表す.0~1の浮動小数点数を取得するにはrand()/double(RAND_MAX)を使用します.