#计算πfrom random import randomfrom math import sqrtfrom time import perf_counterstart_time = perf_counter()DARTS = 12000hits = 0perf_counter()for i in range(1,DARTS):print('程序运行中····','目前循环到第',i,'次')x,y = random(),random()dist = sqrt(x**2 + y**2)if dist <= 1.0:hits = hits + 1pi = 4 * (hits/DARTS)end_time = perf_counter()print('pi的值', pi)run_time = end_time - start_timeprint('程序运行时间', run_time,'s')
以下是对这段代码的精简解析:
代码功能概述
这段代码运用蒙特卡罗方法来估算圆周率 \(\pi\) 的值,并且记录程序的运行时间。蒙特卡罗方法借助随机抽样的方式来近似求解数学问题,在此处是通过在单位正方形内随机生成点,统计落在单位圆内的点的数量,进而估算 \(\pi\) 的值。
代码逐行解析
- 导入模块
python
from random import random
from math import sqrt
from time import perf_counter
from random import random:从 random模块导入random函数,此函数可生成一个位于 \([0, 1)\) 区间的随机浮点数。from math import sqrt:从 math模块导入sqrt函数,该函数用于计算平方根。from time import perf_counter:从 time模块导入perf_counter函数,此函数能够提供高精度的时间测量,可用于记录程序的运行时间。
- 记录开始时间
python
start_time = perf_counter()
调用 perf_counter() 函数获取当前时间,将其赋值给 start_time 变量,以此记录程序的开始时间。
- 设置参数
python
DARTS = 12000
hits = 0
DARTS:设定随机投点的总数,这里设定为 12000 次。 hits:用于统计落在单位圆内的点的数量,初始值设为 0。
- 无用的时间调用(可删除)
python
perf_counter()
这行代码调用了 perf_counter() 函数,但并未将返回值赋值给任何变量,所以没有实际作用,可以删除。
- 循环投点并统计
python
for i in range(1, DARTS):
print('程序运行中····','目前循环到第', i, '次')
x, y = random(), random()
dist = sqrt(x**2 + y**2)
if dist <= 1.0:
hits = hits + 1
for i in range(1, DARTS):循环 DARTS - 1次,模拟投点过程。print('程序运行中····','目前循环到第', i, '次'):在每次循环时打印当前的循环次数,以此显示程序的运行进度。 x, y = random(), random():生成两个位于 \([0, 1)\) 区间的随机浮点数,分别作为点的 x 和 y 坐标。 dist = sqrt(x**2 + y**2):计算该点到原点的距离。 if dist <= 1.0:判断该点是否落在单位圆内,若落在圆内,则将 hits加 1。
- 估算圆周率
python
pi = 4 * (hits / DARTS)
依据蒙特卡罗方法的原理,单位圆的面积与单位正方形的面积之比近似等于落在圆内的点的数量与总投点数量之比。
- 记录结束时间
python
end_time = perf_counter()
调用 perf_counter() 函数获取当前时间,将其赋值给 end_time 变量,以此记录程序的结束时间。
- 输出结果
python
print('pi的值', pi)
run_time = end_time - start_time
print('程序运行时间', run_time, 's')
print('pi的值', pi):打印估算得到的圆周率 \(\pi\) 的值。 run_time = end_time - start_time:计算程序的运行时间。 print('程序运行时间', run_time, 's'):打印程序的运行时间。
优化建议
-
可以去除无用的 perf_counter()调用。 -
为了提升程序的性能,可减少 print语句的使用,因为频繁的打印操作会显著降低程序的运行速度。
优化后的代码如下:
python
from random import random
from math import sqrt
from time import perf_counter
start_time = perf_counter()
DARTS =12000
hits =0
for _ inrange(DARTS):
x, y = random(), random()
dist = sqrt(x**2+ y**2)
if dist <=1.0:
hits = hits +1
pi =4*(hits / DARTS)
end_time = perf_counter()
print('pi的值', pi)
run_time = end_time - start_time
print('程序运行时间', run_time,'s')
优化后的代码删除了无用的时间调用和不必要的打印语句,使程序更加简洁高效。
总结
-
此代码借助蒙特卡罗方法模拟投点过程来估算 的值。 -
原代码在计时部分存在问题,修正后的代码正确记录了程序的开始和结束时间,进而能准确计算出程序的运行时间。 -
增加模拟投点的次数 DARTS,可以提高估算的精度。

