http://www.cnblogs.com/tanky_woo/archive/2010/12/11/1902921.html
接着上一篇: 随机化算法(1) — 随机数
在这章开篇推荐下chinazhangjie总结的随机算法,因为咱两看的是同一本书,所以大家也可以去参考下他的,总结的很不错。
http://www.cnblogs.com/chinazhangjie/archive/2010/11/11/1874924.html
(顺便再PS一下,小杰也是我论坛的C/C++问题求助板块的版主,C/C++小牛)
这一章我就把书中的一个例子举出来了,感觉虽然很简单,但是很有意思。
用随机投点法计算Pi值
设有一半径为r的圆及其外切四边形。向该正方形随机地投掷n个点。设落入圆内的点数为k。由于所投入的点在正方形上均匀分布,因而所投入的点落入圆内的概率为(Pi*r*r)/(4*r*r)= Pi/4 。所以当n足够大时,k与n之比就逼近这一概率。从而,PI 约等于 (4*k)/n.
如下图:
因为代码里用到了上一章《概率算法(1) — 随机数》里的RandomNumber类,所以大家可以先把前一章看看。
我把这个伪随机类再贴一遍:
const unsigned long maxshort = 65535L;
const
unsigned
long
multiplier
=
1194211693L
;
const unsigned long adder = 12345L ;
class RandomNumber{
private :
// 当前种子
unsigned long randSeed;
public :
// 构造函数,默认值0表示由系统自动产生种子
RandomNumber(unsigned long s = 0 );
// 产生0 ~ n-1之间的随机整数
unsigned short Random(unsigned long n);
// 产生[0, 1) 之间的随机实数
double fRandom();
};
// 产生种子
RandomNumber::RandomNumber(unsigned long s)
{
if (s == 0 )
randSeed = time( 0 ); // 用系统时间产生种子
else
randSeed = s;
}
// 产生0 ~ n-1 之间的随机整数
unsigned short RandomNumber::Random(unsigned long n)
{
randSeed = multiplier * randSeed + adder;
return (unsigned short )((randSeed >> 16 ) % n);
}
// 产生[0, 1)之间的随机实数
double RandomNumber::fRandom()
{
return Random(maxshort) / double (maxshort);
}
const unsigned long adder = 12345L ;
class RandomNumber{
private :
// 当前种子
unsigned long randSeed;
public :
// 构造函数,默认值0表示由系统自动产生种子
RandomNumber(unsigned long s = 0 );
// 产生0 ~ n-1之间的随机整数
unsigned short Random(unsigned long n);
// 产生[0, 1) 之间的随机实数
double fRandom();
};
// 产生种子
RandomNumber::RandomNumber(unsigned long s)
{
if (s == 0 )
randSeed = time( 0 ); // 用系统时间产生种子
else
randSeed = s;
}
// 产生0 ~ n-1 之间的随机整数
unsigned short RandomNumber::Random(unsigned long n)
{
randSeed = multiplier * randSeed + adder;
return (unsigned short )((randSeed >> 16 ) % n);
}
// 产生[0, 1)之间的随机实数
double RandomNumber::fRandom()
{
return Random(maxshort) / double (maxshort);
}
主文件Main: