前言
蛮力法简单粗暴,但是却也通俗易用,充分利用计算机快速的优点,所以可以用来解决很多算法问题。本文通过使用蛮力法来求解圆周率。
算法设计
用蛮力法求PI的基本思想是:
- 将
x
x
x 轴上的区间[-1, 1] 划分成
n
n
n 份,将
y
y
y 轴上的区间[-1, 1] 划分成
n
n
n 份,可以得到
n
2
n^2
n2 个交点,如下图所示。
- 统计落在圆内的点的点的个数 h i t hit hit
- 设矩形面积为
S
R
S_R
SR,圆面积为
S
C
S_C
SC,则以下等式成立
h i t n 2 = S R S C \frac{hit}{n^2} = \frac{S_R}{S_C} n2hit=SCSR
, 其中
S
R
=
r
2
,
S
C
=
π
r
2
\ S_R =r^2, S_C = \pi r^2
SR=r2,SC=πr2,将其代入可得:
h
i
t
n
2
=
π
r
2
r
2
=
π
\frac{hit}{n^2} = \frac{\pi r^2}{ r^2} = \pi
n2hit=r2πr2=π
所以, π \pi π 可以表示为 命中点数和总点数的比值。根据这个关系编写以下代码:
算法实现
class Pi{
public static void main(String[] args) {
System.out.printf("Pi = %f, n = 10\n", calculatePi(10));
System.out.printf("Pi = %f, n = 100\n", calculatePi(100));
System.out.printf("Pi = %f, n = 1000\n", calculatePi(1000));
System.out.printf("Pi = %f, n = 10000\n", calculatePi(10000));
}
static double calculatePi(int n) {
long hit = 0;
for (int x = -n; x < n; x++)
for (int y = -n; y < n; y++)
hit = x * x + y * y <= n * n? hit + 1 : hit;
return 1.0 * hit / n/ n;
}
}
经测试,在不同的 n n n 值下,可以求得不同精度的 π \pi π 的值。
Pi = 3.150000, n = 10
Pi = 3.141500, n = 100
Pi = 3.141547, n = 1000
Pi = 3.141591, n = 10000
结论
通过以上算法,虽然代码很简洁,但是却可以求得圆周率小数点后5位有效数字,能够满足大部分场合的应用。通常,最常见与之相比的就是蒙特卡罗法,即利用随机生成点的方法进行求解。两者相比,蒙特卡罗的随机不确定性决定了其精度有限,而蛮力法如果按极限的思想来考虑,只要 n n n 足够大,可以获得更高的精度,且不需要随机值生成算法,效率更高。