code记事本

code记事本
posts - 1, comments - 0, trackbacks - 0, articles - 0

一个C++封装的随机类

Posted on 2010-10-08 11:55 沈军 阅读(395) 评论(0)  编辑 收藏 引用
  1 /*C++封装的随机类,Windows系统自带的纸牌游戏就是用的此程序(本程序接口做了细微的修改),效率比系统自带的随机函数高不少,可以直接运用到自己的项目中去*/
  2 
  3 (.H文件)
  4 #ifndef RANDOMSAMPLE_HEAD
  5 #define RANDOMSAMPLE_HEAD
  6 
  7 #define CMATH_N 624
  8 #define CMATH_M 397
  9 #define CMATH_MATRIX_A 0x9908b0df //(0~2567483615)
 10 #define CMATH_UPPER_MASK 0x80000000 //(0~2147483648)
 11 #define CMATH_LOWER_MASK 0x7fffffff //(0~2147483647)
 12 
 13 //Tempering parameters
 14 #define CMATH_TEMPING_MASK_B 0x9d2c5680 //(0~2636928640)
 15 #define CMATH_TEMPING_MASK_C 0xefc60000 //(0~4022730752)
 16 #define CMATH_TEMPING_SHIFT_U(y) (y>>11)
 17 #define CMATH_TEMPING_SHIFT_S(y) (y>>7)
 18 #define CMATH_TEMPING_SHIFT_T(y) (y>>15)
 19 #define CMATH_TEMPING_SHIFT_L(y) (y>>18)
 20 
 21 //随机类
 22 class RandomSample
 23 {
 24 public:
 25     RandomSample(void);
 26     ~RandomSample(void);
 27 
 28 public:
 29     unsigned int Random(unsigned int n);////返回一个0~n的数(不包含n)
 30     bool GetProbability (unsigned int nOdds, unsigned int nSpace);//计算概率
 31 
 32 private:
 33     unsigned long GetCpuCycCount();//CPU运行时钟
 34     unsigned int GetRandomSeed(void);//获取随机种子
 35     void SetRandomSeed(unsigned int n);//设置随机种子
 36     void Randomize(void);//以CPU频率设置种子
 37 
 38 private:
 39     unsigned int rseed;//种子
 40     unsigned long mt[CMATH_N];//状态向量
 41     int mti;
 42 };
 43 #endif
 44 
 45 (.cpp文件)
 46 #include "stdafx.h"
 47 #include "RandomSample.h"
 48 
 49 RandomSample::RandomSample(void)
 50 {
 51     rseed = 1;
 52     mti = CMATH_N + 1;
 53 }
 54 
 55 RandomSample::~RandomSample(void)
 56 {
 57 }
 58 
 59 //返回一个0~n的数(不包含n)
 60 unsigned int RandomSample::Random(unsigned int n)
 61 {
 62     Randomize();
 63     unsigned long y;
 64     static unsigned long ULarr[2= {0x0, CMATH_MATRIX_A};
 65 
 66     if (n == 0)
 67         return 0;
 68     if (mti >= CMATH_N)//同时产生N个数字
 69     {
 70         int kk;
 71         if(mti == CMATH_N + 1)//如果发生器没有被调用
 72             SetRandomSeed(4357);//使用一个默认的值作为种子
 73 
 74         for(kk = 0; kk < CMATH_N - CMATH_M; kk++)
 75         {
 76             y = (mt[kk] & CMATH_UPPER_MASK) | (mt[kk+1& CMATH_LOWER_MASK);
 77             mt[kk] = mt[kk+CMATH_M] ^ (y>>1^ ULarr[y & 0x1];
 78         }
 79         for (;kk < CMATH_N-1;kk++)
 80         {
 81             y = (mt[kk] & CMATH_UPPER_MASK) | (mt[kk+1& CMATH_LOWER_MASK);
 82             mt[kk] = mt[kk+(CMATH_M - CMATH_N)] ^ (y>>1^ ULarr[y & 0x1];
 83         }
 84         y = (mt[CMATH_N - 1& CMATH_UPPER_MASK) | (mt[0& CMATH_LOWER_MASK);
 85         mt[CMATH_N-1= mt[CMATH_M-1^ (y>>1^ ULarr[y & 0x1];
 86 
 87         mti = 0;
 88     }
 89 
 90     y = mt[mti++];
 91     y ^= CMATH_TEMPING_SHIFT_U(y);
 92     y ^= CMATH_TEMPING_SHIFT_S(y) & CMATH_TEMPING_MASK_B;
 93     y ^= CMATH_TEMPING_SHIFT_T(y) & CMATH_TEMPING_MASK_C;
 94     y ^= CMATH_TEMPING_SHIFT_L(y);
 95 
 96     return y%n;
 97 
 98 }
 99 
100 //设置随机种子
101 void RandomSample::SetRandomSeed(unsigned int n)
102 {
103     mt[0= n & 0xffffffff;
104     for(mti = 1; mti <CMATH_N; mti++)
105         mt[mti] = (69069 * mt[mti - 1]) & 0xffffffff;
106     rseed = n;
107 }
108 
109 //获取随机种子
110 unsigned int RandomSample::GetRandomSeed(void)
111 {
112     return rseed;
113 }
114 
115 //以CPU频率设置种子
116 void RandomSample::Randomize(void)
117 {
118     SetRandomSeed(GetCpuCycCount());
119 }
120 
121 //类似于CPU频率的东西
122 inline  unsigned long RandomSample::GetCpuCycCount()
123 {
124     _asm
125     {
126         _emit 0x0F;
127         _emit 0x31;
128     }
129 }
130 
131 //参    nOdds--希望得到的几率值
132 //数    nSpace--随机数的取值范围(0~nSpace-1)
133 bool RandomSample::GetProbability(unsigned int nOdds, unsigned int nSpace)
134 {  
135     Randomize();
136     unsigned int nRandomNumber = Random(nSpace);
137     if (nOdds > nRandomNumber)
138     {      
139         return true;
140     }
141     else
142     {
143         return false;
144     }
145 }
146 
147 (测试代码)
148 #include "stdafx.h"
149 #include "RandomSample.h"
150 #include <iostream>
151 using namespace std;
152 
153 int _tmain(int argc, _TCHAR* argv[])
154 {
155     RandomSample random;
156     int j = 0;
157     int nCount = 100;
158     for (int i = 0; i < nCount; i++)
159     {
160         //计算概率
161         if (random.GetProbability(90,100))
162         {
163             j++;
164         }
165     }
166     cout<<"运行"<<nCount<<"次的几率为 %"<<j;
167     getchar();
168     return 0;
169 }

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理