C++ 如何用概率来估算圆周率:有一个人在CSDN BBS上提问一段程序,引发我的思考和所得:

 1 #include <stdlib.h>
2 #include <stdio.h>
3 #define LOOP 1000
4 void main()
5 {
6 int rgnC=0;
7 for(int i=0;i<LOOP;i++)
8 {
9 int x=rand();
10 int y=rand();
11 if(x*x+y*y<RAND_MAX*RAND_MAX)
12 rgnC++;
13 }
14 printf("%d\n",rgnC);
15 }

  他的问题是:这段程序是不是和1/4圆和正方形的大小有关,为什么LOOP越大,rgnC越大,是不是程序错了。

  其实LOOP越大,rgnC必然越大,但是rgnC/LOOP确是收敛的。

  开始我的回答就是这些,没有去想这段程序的作用和这个收敛值到底是干嘛的。直到后来又有一个人给出了这个程序是用来估算圆周率的,我才发现我的思考是多么的不深刻和不完善。

  其实随着LOOP的增大,rgnC/LOOP确实会收敛于一个值π/4。这是用概率来估算圆周率的一个方法。

  圆的面积公式:C = π × r^2  公式1

  正方形面积公式:S = k^2     公式2

  这里用1/4圆,它的半径r和正方形的边长k相等。

  因为要计算π,所以圆的面积是无法用公式1计算出来的。所以可以考虑用概率的方法。

  我们可以构建如上的模型,我们可以随意在正方区域内撒点(就像撒米在地上一样),然后我们知道撒入1/4圆(黑色)区域内的概率是P = (C/4)/S = π/4,也就是说得到P,就可以得到π。

  可以用程序很轻松的得到解决。

  改造后的程序代码如下:

 1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main(int argc, char *argv[])
5 {
6 int i = 0,j = 0;
7 int test = 0,x,y;
8 for(i = 100;i<1000000000;i*=10){
9 test = 0;
10 for(j = 0;j<i;j++){
11 x = rand();
12 y = rand();
13 if((x*x + y*y) < RAND_MAX*RAND_MAX){
14 test++;
15 }
16 }
17 printf("scale = %d,π= %f\n",i,(double)test*4/i);
18 }
19 return 0;
20 }

  程序很好理解:RAND_MAX为正方形边长,x,y为随机的数,X*X+Y*Y = R^2,即随机生成的圆的面积/π ,若这个数小于 RAND_MAX*RAND_MAX,即为黑色区域(1/4圆)面积/π,则test自增1。

  说的通俗一点就是在正方形区域内随意撒点,若在黑色区域内则test++,最后test和测试范围 i 相除可以近似得到概率P,则可近似得到圆周率π = P*4

  程序运行结果如下:

scale = 100,π= 3.200000
scale = 1000,π= 3.076000
scale = 10000,π= 3.113200
scale = 100000,π= 3.139800
scale = 1000000,π= 3.139908
scale = 10000000,π= 3.140975
scale = 100000000,π= 3.141385

推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架
新浪微博粉丝精灵,刷粉丝、刷评论、刷转发、企业商家微博营销必备工具"