隨機數模擬拋硬幣實驗

在現實計算機上無法產生真正的隨機數,因此在隨機化算法中使用的隨機數都是一定程度上隨機的,即僞隨機數。線性同餘法是產生僞隨機數最常用的方法(這裏不介紹)。


下面用計算機產生大的僞隨機數來模擬拋硬幣試驗。假設拋10次硬幣,每次拋硬幣得到正面和反面是隨機的。拋10次硬幣構成一個事件。調用Random(2)返回一個二值結果。返回0表示拋硬幣得到反面,返回1表示得到正面。下面的算法TossCoins模擬拋10次硬幣這一事件。在主程序中反覆用函數TossCoins模擬拋10次硬幣這一事件50000次。用head[i](0<=i<=10)記錄這50000次模擬恰好得到i次正面的次數。最終輸出模擬拋硬幣時間得到正面事件的頻率圖。

#include<iostream>
#include<time.h>
#include <iomanip>
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); //構造函數,默認值0表示由系統自動生成種子
		unsigned short Random(unsigned long n); //產生0到n-1之間的隨機數
		double fRandom(void); //產生[0,1)之間的隨機數
};

RandomNumber::RandomNumber(unsigned long s)  //產生種子
{
	if(s==0)
		randSeed=time(0);  //用系統時間產生種子
	else
		randSeed=s;  //由用戶提供種子
}

unsigned short RandomNumber::Random(unsigned long n) //產生0到n-1之間的隨機整數
{
	randSeed=multiplier*randSeed+adder;
	return(unsigned short)((randSeed>>16)%n);
}

double RandomNumber::fRandom(void)   //產生[0,1)之間的隨機數
{
	return Random(maxshort)/double(maxshort);
}



int TossCoins(int numberCoins)
{
	//隨機拋硬幣
	static RandomNumber coinToss;
	int i,tosses=0;
	for(i=0;i<numberCoins;i++)
		//Random(2)=1表示正面
		tosses+=coinToss.Random(2);
	return tosses;
}

//測試
void main(void)
{
	//模擬隨機拋硬幣
	const int NCOINS=10;
	const long NTOSSES=50000L;
	//head[i]是得到i次正面的次數
	long i,heads[NCOINS+1];
	int j,position;
	//初始化數組heads;
	for(j=0;j<NCOINS+1;j++)
		heads[j]=0;
	//重複50 000次模擬實驗
	for(i=0;i<NTOSSES;i++)
		heads[TossCoins(NCOINS)]++;
	//輸出頻率圖
	for(i=0;i<=NCOINS;i++)
	{
		position=int(float(heads[i])/NTOSSES*72);
		cout<<setw(6)<<i<<" ";
		for(j=0;j<position-1;j++)
			cout<<" ";
		cout<<"*"<<endl;
	}	
}



/*
結果:

     0 *
     1 *
     2   *
     3        *
     4              *
     5                 *
     6              *
     7        *
     8   *
     9 *
    10 *
Press any key to continue

  */


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章