1.割圆法计算圆周率
"""用正六边形近似圆,计算圆周率
π = 周长/(2*圆的半径)得到π的近似值。
# 半径为1的圆内接正6边形边长也是1
# 边长 side_length
# 半径 radius
# 圆周率 pi
# 三角形的高 height
"""
side_length = 1 # 初始边长
edges = 6 # 初始边数
height = 1 - math.sqrt(1 - (side_length / 2) ** 2)
side_length = math.sqrt(height ** 2 + (side_length / 2) ** 2)
pi = side_length * edges
print(pi) # 3.105828541230249
2.割圆法计算圆周率(思政,中华文明,精益求精)
import math
def cutting_circle(times):
"""参数times为分割次数
π = 周长/(2*圆的半径)得到π的近似值。
# 半径为1的圆内接正6边形边长也是1
# 边长 side_length
# 半径 radius
# 圆周率 pi
# 三角形的高 height
"""
side_length = 1 # 初始边长
edges = 6 # 初始边数
for i in range(times):
height = 1 - math.sqrt(1 - (side_length / 2) ** 2)
side_length = math.sqrt(height ** 2 + (side_length / 2) ** 2)
edges = edges * 2 # 每割一次,边数量加倍
pi = side_length * edges / 2
return pi
if __name__ == '__main__':
print(cutting_circle(2)) # 3.1326286132812378
print(cutting_circle(20)) # 3.141592653589663
3.莱布尼茨级数计算圆周率
数学思维
def leibniz_of_pi(error):
"""接收用户输入的浮点数阈值为参数,用格雷戈里-莱布尼茨级数计算圆周率,返回圆周率值"""
n, quarter_of_pi, sign = 1, 0, 1
while 1 / (2 * n - 1) > error:
quarter_of_pi = quarter_of_pi + sign * 1 / (2 * n - 1)
n = n + 1
sign = -sign
pi = 4 * quarter_of_pi
return pi
if __name__ == '__main__':
print(leibniz_of_pi(1e-6)) # 3.141590653589692
4.蒙特卡洛法计算圆周率
统计方法,蒙特卡洛算法
import random
def monte_carlo_pi(num):
"""接收一个表示随机次数的整数,用蒙特卡洛法计算圆周率,返回一个浮点数"""
hits = 0 # 落在圆内的计数器初值设为 0
for i in range(1, num + 1):
x, y = random.uniform(-1, 1), random.uniform(-1, 1), # 生成两个随机数模拟一个点的坐标
pos = (x ** 2 + y ** 2) ** 0.5 # 计算坐标(x,y)到原点的距离
if pos <= 1.0: # 如果距离小于等于1,点在圆内
hits = hits + 1
pi = 4 * (hits / num)
return pi
if __name__ == '__main__':
print(monte_carlo_pi(1000000)) # 3.142968
5.梅钦级数计算圆周率
数学思维,效率意识
import math
def machin_of_pi():
"""用梅钦级数计算圆周率,返回圆周率值"""
quarter_of_pi = 4 * math.atan(1/5) - math.atan(1/239)
pi = 4 * quarter_of_pi
return pi
if __name__ == '__main__':
print(machin_of_pi()) # 3.1415926535897936
6.拉马努金公式计算圆周率
数学思维,效率意识,循环在数学中的应用
import math
def ramanujan_of_pi(n):
"""接收一个正整数n为参数,用拉马努金公式的前n项计算圆周率并返回。"""
result = 0
for i in range(n):
result = result + ((2 * 2 ** 0.5)) * (math.factorial(4 * i) * (1103 + 26390 * i)) / (
math.pow(math.factorial(i), 4) * math.pow(396, 4 * i)) / 9801
pi = 1 / result
return pi
if __name__ == '__main__':
print(ramanujan_of_pi(2)) # 3.1415926535897936
7.演示割圆法
可视化,函数
def draw_circle(r, side_num):
"""创建图形和轴,用折线图绘制正多边形。
@参数 r:圆的半径
@参数 side_num:正多边形的边数
"""
fig, ax = plt.subplots() # 创建图形和轴
plt.subplots_adjust(left=0.1, bottom=0.25)
x, y = xy_of_polygon(r, side_num)
plt.plot(x, y, lw=2, color='red') # 设置线宽和颜色
ax.set_aspect('equal') # 设置坐标轴纵横比相等
ax.set_xlim(-r-5, r+5) # 设置x轴刻度起止值
ax.set_ylim(-r-5, r+5)
plt.draw() # 重新绘制多边形
plt.show() # 显示图形
def cutting_circle(times):
"""
接收表示分割次数的整数n 为参数,计算分割n 次时正多边形的边数和圆周率值,返回边数和圆周率值。
@参数 times:分割次数
π = 周长/(2*圆的半径)得到π的近似值。
# 半径为1的圆内接正6边形边长也是1
# 边长 side_length
# 半径 radius
# 圆周率 pi
# 三角形的高 height
>>> cutting_circle(4)
3.14103195089051
"""
side_length = 1 # 初始边长
edges = 6 # 初始边数
for i in range(times):
height = 1 - math.sqrt(1 - (side_length / 2) ** 2)
side_length = math.sqrt(height ** 2 + (side_length / 2) ** 2)
edges = edges * 2 # 每割一次,边数量加倍
draw_circle(300, edges) # 调用此函数可演示割圆效果,每次循环绘制一个近似圆,关闭后看下一个
pi = side_length * edges / 2
return pi
8.matplotlib演示蒙特卡洛
import matplotlib.pyplot as plt
def monte_carlo_show(in_circle_lst, out_circle_lst):
"""
@参数 in_circle_lst:落在圆内的点的坐标列表
@参数 out_circle_lst:落在圆外的点的坐标列表
"""
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.figure(figsize=(11, 11)) # 设置画布长宽
x_in_circle = [x[0] for x in in_circle_lst] # 落在圆内的点的列表x
y_in_circle = [x[1] for x in in_circle_lst] # 落在圆内的点的列表y
x_out_circle = [x[0] for x in out_circle_lst] # 落在圆外的点的列表x
y_out_circle = [x[1] for x in out_circle_lst] # 落在圆外的点的列表y
plt.scatter(x_out_circle, y_out_circle, s=10, facecolors='blue') # 绘制散点,落在圆外在点颜色用蓝色
plt.scatter(x_in_circle, y_in_circle, s=5, facecolors='red') # 绘制散点,落在圆内在点颜色用红色
plt.title('蒙特卡洛法计算圆周率演示') # 图的标题
plt.show() # 显示绘制结果
9.turtle演示蒙特卡洛
import turtle
# 给出turtle模板,学生填monte_carlo代码,帮助学生理解算法,了解turtle绘图
def monte_carlo_pi_turtle(n, s):
"""用turtle绘图模拟蒙特卡洛n次结果"""
random.seed(s)
turtle.tracer(1000)
turtle.pensize(4)
turtle.penup()
turtle.goto(-300, -300)
turtle.pendown()
for i in range(4):
turtle.forward(600)
turtle.left(90)
turtle.forward(300)
turtle.pencolor('green')
turtle.circle(300)
hits = 0 # 落在圆内的计数器初值设为 0
for i in range(1, n + 1):
x, y = random.uniform(-1, 1), random.uniform(-1, 1) # 生成两个随机数模拟一个点的坐标
pos = (x ** 2 + y ** 2) ** 0.5 # 计算坐标(x,y)到原点的距离
if pos <= 1.0: # 如果距离小于等于1,点在圆内
hits = hits + 1
turtle.pencolor('red') # 落在圆内在点颜色用红色
else: # 如果距离大于1,点在圆外
turtle.pencolor('blue') # 落在圆内在点颜色用蓝色
turtle.penup()
turtle.goto(x * 300, y * 300) # 画笔抬起并移动到数值放大400倍的x,y处
turtle.pendown()
turtle.dot(3) # 画一个半径为 3 的圆点
if i % 10000 == 0: # 实验为10000的倍数次时
turtle.pencolor('black')
pi = 4 * (hits / i) # 根据落在圆内外的点数量估算PI值
turtle.penup() # 画笔抬起
turtle.goto(320, 150 - i // 1000 * 30) # 移动到区域外记录当前PI值
turtle.pendown() # 画笔抬起
turtle.write("{}次时PI的值是{:.4f}".format(i, pi), font=("宋体", 18, "normal"))
turtle.hideturtle() # 隐藏光标
turtle.update() # 刷新
turtle.done() # 结束绘制