ソースファイル(1個予想)
ソースファイル(4個予想)

ソースファイルのプロジェクトのEducationはさいころの目の予測です
またRouletteはルーレットの目の予測です
Rouletteについて解説します
この予測はデータ上あまり出ていない目を挙げます
RANGEは直近データ保持数
RATEは直近データの重み
それが2種類
試行回数g_nがg_n%RANGE[tryn]==0になると
g_data[tryn][work][data]:tryn:種類:work:直近データの切り替え:data:直近データ:
g_data[tryn][1][i]=(int)((float)g_data[tryn][0][i]/RATE[tryn]);
このような式によってデータが蓄積します

ルーレットの的中確率(1/38)が2.63%
的中倍率が36倍で94.7%の期待値です
100%の期待値が持てる確率(1/36)は2.78%
ルーレットの的中確率(4/38)が10.5%
的中倍率が9倍で94.7%の期待値です
100%の期待値が持てる確率(1/9)は11.1%
予測を0固定にしても勝率は変わりません
振る舞いは問わずただ仕組みの確率だけに収束します

RandMax以上の組み合わせを実現するには、時間滑りを導入して、
const unsigned int RND_PERIOD=16;
int TimeRandom(int nmin,int nmax)
{
 static int cnt=0;
 unsigned int t=timeGetTime()%RND_PERIOD,i;
 for(i=0;i<t;i++)rand();
 if(nmax<nmin){int tmp=nmax;nmax=nmin;nmin=tmp;}
 return (int)(((double)rand()*((double)nmax-(double)nmin+1.0))/((double)RAND_MAX+1.0));
}
とするか、或いは、基数法則に則り、
long int LongRandom(long int nmin,long int nmax)
{
 double a=(double)rand()/((double)RAND_MAX+1.0);
 double b=(double)rand()/((double)RAND_MAX*(double)RAND_MAX+1.0);
 if(nmax<nmin){long int tmp=nmax;nmax=nmin;nmin=tmp;}
 long int c=(long int)((a+b)*(((double)nmax-(double)nmin)+1.0));
 return c;
}
とするかです
long int Random(long int min,long int max)
{
 return (long int)((double)rand()*(double)rand()*(((double)max-(double)min)+1.0)/((double)RAND_MAX*(double)RAND_MAX+1.0));
}
でダメな理由は、(double)rand()*(double)rand()で合成数しか生成できないので、あまり意味はありません
従って、基数法則に則って、rand()*BASE+rand()というような形で、正規化して0-1.0範囲にしたいので、
rand()/BASE+rand()/BASE/BASEという先の形にしなければなりません

VC++では、
static long x=1;
int rand() { x=x*214013+2531011; return(int)(x>>16)&32767; }
void srand(long s) { x=s; }
みたいです
これで0-32767の一様乱数rand()が得られたら、
32768を基数として、基数法則から、
rand()*BASE+rand()の形にすれば、0-2147483647の一様乱数に戻せたことになります

rand()を使わない方法では、XorShiftというものがあるそうで、
static long int xors=123456789;
long int xorsRand(){
 static long int y=362436069,z=521288629,w=88675123;
 long int t;
 t=(xors^(xors<<11));xors=y;y=z;z=w; return( w=(w^(w>>19))^(t^(t>>8)) );
}

 void xorsSRand(){
 int i;
 srand((unsigned)time(NULL));
 for(i=0;i<rand();i++) xorsRand();
}

long int XORSRandom(long int nmin,long int nmax)
{
 double a=(double)(xorsRand()%LONG_MAX)/(double)LONG_MAX;
 if(nmax<nmin){long int tmp=nmax;nmax=nmin;nmin=tmp;}
 long long int c=(long int)(a*(((double)nmax-(double)nmin)+1.0));
 return c;
}
とします

また、組み合わせを無限に作りたいというのであれば、
rand()/BASE+rand()/BASE/BASE+rand()/BASE/BASE/BASE+・・・と気のすむまで続ければよいです
double DoubleXORSRandom()
{
 double a=(double)(xorsRand()%LONG_MAX)/((double)LLONG_MAX);
 double b=(double)(xorsRand()%LONG_MAX)/((double)LLONG_MAX*(double)LLONG_MAX);
 return a+b;
}
まあ、doubleの有効桁は15桁なので丸められますけどね





VBスケルトンコード
以上、乱数やら3Dエンジンやらのスケルトンコードをまとめておいた





戻る