27 March 2013

使用蒙特卡洛方法求圆周率的方法比较简单。其原理是:在一个边长为l的正方形中有一个半径也为l的四分之一圆,如图所示。在这个正方形中仍石子,统计命中园的次数S1和一共仍的次数S2。假设半径足够大,仍的次数足够多。那么,S1和S2便可以代表四分之一园的面积和正方形的面积。所以工具如下公式,可以得到圆周率的计算方法。这个过程与半径无关。

实现的过程中,需要使用随机数来模拟扔石子的过程。在(0,l)的范围内随机出一对横坐标x和纵坐标y,计算这个点到原点(0,0)的距离来判断是否仍到了圆内。在理论上,圆周率的计算和半径无关,但是在实际计算过程中,因为半径会影响仍石子随机坐标的范围,所以还是会影响到精确度,半径越大越好。产生随机数试用stdlib库中的rand和srand分别来产生随机数和随机种子。随机种子调用时间来生成。具体实现如下:

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cmath>
using namespace std;
int main(int argc, char *argv[]) {
	int times = atoi(argv[1]); // 获得用户输入的模拟次数

	const int R = 1000; // 半径
	int count = 0;

	srand((unsigned)time(0)); // 通过获得时间来产生随机数种子
	int i;
	for (i = 0; i < times; i++)
	{
		int x = rand() % (R + 1); // 生成随机横坐标和纵坐标
		int y = rand() % (R + 1);
		if (x * x + y * y <= R * R) // 判断是否在圆内
		{
			count++;
		}
	}
	float pi = count * 4.0f / times; // 根据统计结果计算出圆周率
	cout << pi << endl;

	return 0;
}

原文链接:蒙特卡洛求圆周率,转载请注明来源!

EOF