2009년 11월 26일 목요일

random


CRnd.h

#ifndef CRnd_h__
#define CRnd_h__

/* Period parameters */
#define CMATH_N 624
#define CMATH_M 397
#define CMATH_MATRIX_A 0x9908b0df   /* constant vector a */
#define CMATH_UPPER_MASK 0x80000000 /* most significant w-r bits */
#define CMATH_LOWER_MASK 0x7fffffff /* least significant r bits */

/* Tempering parameters */
#define TEMPERING_MASK_B 0x9d2c5680
#define TEMPERING_MASK_C 0xefc60000
#define TEMPERING_SHIFT_U(y)  (y >> 11)
#define TEMPERING_SHIFT_S(y)  (y << 7)
#define TEMPERING_SHIFT_T(y)  (y << 15)
#define TEMPERING_SHIFT_L(y)  (y >> 18)

#define rnd(n) {CRnd::Get()->Random(n)}

class CRnd
{
CRnd(void);
~CRnd();

//데이터
unsigned int rseed;
unsigned long mt[CMATH_N]; //상태 벡터를 위한 함수
int mti; //mti==N+1은 mt[n]이 초기화 지되 않았음을 뜻한다.

//함수
public:
static CRnd* Get(){return &ms_cRnd;}
unsigned int Random(unsigned int n);
void SetRandomSeed(unsigned int n);
unsigned int GetRandomSeed(void);
void Randomize(void);

private:
static CRnd  ms_cRnd;

};


#endif // CRnd_h__

CRnd.cpp


#include
#include "CRnd.h"

CRnd CRnd::ms_cRnd;

CRnd::CRnd(void)
{
rseed=1;
mti=CMATH_N+1;

Randomize();
}

CRnd::~CRnd()
{
}


unsigned int CRnd::Random(unsigned int n)
{
unsigned long y;
static unsigned long mag01[2]={0x0,CMATH_MATRIX_A};

if(n==0)
return (0);

/* x가 0이거나 1이면 mag01[x]=x*MATRIX_A */

if(mti>=CMATH_N)
{
int kk;

if(mti == CMATH_N+1)
{
SetRandomSeed(4357);

for(kk=0;kk
y=(mt[kk]&CMATH_UPPER_MASK)|(mt[kk+1]&CMATH_LOWER_MASK);
mt[kk] = mt[kk+CMATH_M]^(y>>1)^mag01[y&0x1];
}

for(kk=0 ; kk
{
y=(mt[kk]&CMATH_UPPER_MASK)|(mt[kk+1]&CMATH_LOWER_MASK);
mt[kk]=mt[kk+(CMATH_M-CMATH_N)]^(y>>1)^mag01[y&0x1];

}

y=(mt[CMATH_N-1]&CMATH_UPPER_MASK)|(mt[0]&CMATH_LOWER_MASK);
mt[CMATH_N-1]=mt[CMATH_M-1]^(y>>1)^mag01[y&0x1];

mti=0;
}

y=mt[mti++];
y^=TEMPERING_SHIFT_U(y);
y^=TEMPERING_SHIFT_S(y)& TEMPERING_MASK_B;
y^=TEMPERING_SHIFT_T(y)& TEMPERING_MASK_C;
y^=TEMPERING_SHIFT_L(y);

return (y%n);

}


void CRnd::SetRandomSeed(unsigned int n)
{
mt[0] = n & 0xffffffff;

for(mti=1;mti
mt[mti]=(69069*mt[mti-1])&0xffffffff;

rseed=n;
}

unsigned int CRnd::GetRandomSeed(void)
{
return (rseed);
}

void CRnd::Randomize(void)
{
SetRandomSeed((unsigned int) time(NULL));
}

How to use CRnd??

int main()
{
 int iTmp=rnd(10);
 printf("%d",iTmp);
 return 0;
}

댓글 없음:

댓글 쓰기