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 }