voip
风的方向
厚德致远,博学敦行!
posts - 52,comments - 21,trackbacks - 0
            学以致用!!!
            随机数可以用来计算概率,面积等!!
         一、随机数,模拟抛硬币正面时间频率图。
         代码如下:
#include<iostream>
#include
<time.h>
using namespace std;
const unsigned long maxshort=65536L;
const unsigned long multiplier=1194211693L;
const unsigned long adder=12345L;

class RandomNumber
{
private:
    unsigned 
long randSeed;                    //随机种子
public:
    RandomNumber(unsigned 
long s=0);            //构造函数,为randSeed置数
    unsigned short Random(unsigned long n);        //获取0~n的一个随机数
    double fRandom(void);                        //获取一个小数
}
;

RandomNumber::RandomNumber(unsigned 
long s)        
{
    
if(s==0
        randSeed
=time(0);                        //这里获取直接用time函数获取了一个时间值当做种子了,没有再用srand函数构造种子了!网上查了下time()函数为从1970年1月1日0时0分0秒到此时的秒数!!!
    else
        randSeed
=s;                    
}


unsigned 
short RandomNumber::Random(unsigned long n)
{
//    printf("randSeed:%lu \nmultiplier:%lu  \nrandSeed*multiplier:%lu\n",randSeed,multiplier,randSeed*multiplier);
    randSeed=multiplier*randSeed+adder;            //这里存在一个越界问题,但是还是会从新获得一个randSeed
//    printf("(randSeed>>16):%lu\n",randSeed>>16);
    return (unsigned short)((randSeed>>16)%n);        //右移16为再与n取余,从而获得一个0~n的随机数,其实我还不明白,为啥还要右移呢?难道是为了随机性?
}


double RandomNumber::fRandom(void)
{
    
return Random(maxshort)/double(maxshort);     
}


int TossCoins(int numberCoins)
{
    
static RandomNumber coinToss;        //注意了这里定义了一个静态变量,在函数反复调用中coinToss的属性值不变,从构造函数的角度来理解,在函数反复调用过程中,该对象是不会重新去构造的(不会重复调用构造函数的)!
    int i,tosses=0;
    
for(i=0;i<numberCoins;i++)            //这里调用Random函数!!
    {
        tosses
+=coinToss.Random(2);        //返回0或1,1表示正面,0表示反面,累计正面朝上的次数
    }

    
return tosses;                        //返回正面朝上的次数
}

void main()
{
    
const int NCOINS=10;                //定义了常量,我从一些牛人哪里看到,我们应该把静态变量看成只读。。。
    const long NTOSSES=50000L;        
    
long i,heads[NCOINS+1];                //h[i]代表NTOSSES次抛NCOINS次抛硬币中i次正面次数,貌似有些拗口,按这个实例来说,应该是做50000次抛10次硬币,然后统计10次中出现0次正面朝上次数,1次正面朝上次数,。。10次正面朝上次数
    int j,position;

    
for(j=0;j<NCOINS+1;j++)
        heads[j]
=0;

    
for(i=0;i<NTOSSES;i++)                //累计
        heads[TossCoins(NCOINS)]++;

    cout
<<"head结果:";
    
for(i=0;i<=NCOINS;i++)                //输出h结果
    {
        cout
<<heads[i]<<" ";
    }


    cout
<<endl;

    
for(i=0;i<=NCOINS;i++)            //模拟抛硬币正面事件平率图
    {
        position
=int (float(heads[i])/NTOSSES*100);//这里有强制类型转换,其实这里计算了概率,通过强制类型转换成整数!!!
        cout<<i<<" ";

        
for(j=0;j<position-1;j++)            //输出空格
            cout<<" ";
        cout
<<"*"<<endl;
    }

}

运行结果如下:
 
         二、随机数,计算∏。基本思想也是运用了概率事件!设有一个半径为r的圆及其外切四边形,向该图形投掷N个点。设落入圆内的点数为K,由于投入的点在正方形上分布均匀,所以落入圆中的概率为∏*R^2/4/R^2,从投点的角度考虑,该概率为K/N,当N足够大时,我们可以近似的认为二者相等。从而∏=4*K/N。
代码如下:
double Darts(int n)
{
    
static RandomNumber dart;
    
int k=0;
    
for(int i=1;i<=n;i++)
    
{
        
double  x=dart.fRandom();
        
double  y=dart.fRandom();
        
if((x*x+y*y)<=1)
            k
++;
    }

    
return 4*k/double(n);
}

当n=500000000时,运行结果如下:
 

printf输出:http://hi.baidu.com/jiaju111/blog/item/dcd7fd8ba9a7fa1ac9fc7ae2.html

C语言时间日期函数说明:http://www.cnblogs.com/neonlight/archive/2008/08/22/1273942.html
posted on 2010-09-13 15:51 jince 阅读(596) 评论(0)  编辑 收藏 引用 所属分类: 算法设计与分析

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


哈哈哈哈哈哈