摘要:当程序员遇上π,蒙特卡洛算法成了他们的魔法棒。本文用一段C语言代码,将随机点的雨滴洒向数字的海洋,用概率的网捕捉π的踪迹。这不仅是一场算法的探险,更是对编程魔法的一次奇妙展示。
认识蒙特卡洛算法
蒙特卡洛算法是一类基于概率的算法的统称,不是特指某一种算法。
它也被称为统计模拟方法,是指使用随机数来解决很多计算问题的方法。
它的工作原理为两件事:
- 不断抽样
- 逐渐逼近
使用蒙特卡洛算法
今天我们来用它来逼近 π 。
- 首先,我们知道:圆的面积计算公式为
- 接着,我们设想,有一个半径为1的圆,它的面积为 π
- 然后我们用一个边长为 1 的正方形把它切开,让这个圆只保留1/4,此时它的面积则为
- 然后我们在这个正方形里面随机的打点
设我们共随机打了 D 个点,有 C 个点在 1/4圆中,那么C/D就会逼近(π / 4)/ 正方形的面积, 而因为我们正方形的面积是1,所以它也就是会逼近π / 4这个值。
C / D 不断逼近 π / 4, 也就是说,4 * C / D在不断地逼近π。
我们已经知道原理了,现在用代码去逼近它来爽一下。
程序设计思路
这个程序比较简单,我们只要生成随机数,然后用随机数 / 随机数最大值把随机数限制在0~1之间就可以了。
唯一的难点是:怎么判断这个随机点在不在四分之一圆上?
我们可以用勾股定理来轻松解决这个问题:
我们想象中的圆的半径是1,而这个正方形的坐标圆点,它其实就是圆心。所以,我们只要算出坐标距离圆点的直线距离,是否大于等于1,就可以判断出这个点是否在四分之一圆内。
勾股定理:
代码实现
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define MAX 1000000000
int main()
{
long long i = LONG_MAX;
double x = 0.0;
double y = 0.0;
double pi = 0.0;//圆周率
long long count = 0;
//设置随机种子
srand((unsigned)time(NULL));
for (i = 0; i < MAX; i++)
{
//设置随机坐标
x = (double)rand() / RAND_MAX;
y = (double)rand() / RAND_MAX;
printf("%lf %lf\n", x, y);
//判断是否在1/4圆内
if (sqrt(pow(x, 2) + pow(y, 2)) <= 1)
{
//记录随机数在1/4圆内的数量
count++;
}
}
//利用 PI = 4C/D 来求出 PI 的近似值
pi = (4.0 * count) / MAX;
printf("%lf\n", pi);
return 0;
}
运行结果
结论
蒙特卡洛算法通过随机抽样,来逼近复杂问题的解。本文展示了其在计算圆周率 π 的应用。通过在单位正方形内随机生成点,并利用勾股定理判断点是否落在内嵌的四分之一圆内,我们得到了 π 的近似值。这种方法简单有效,随着抽样数量的增加,结果的精度也会提高。
标签:逼近,MAX,圆周率,大数,算法,随机,double,蒙特卡洛 From: https://blog.51cto.com/xuwenda/12112163