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 * edgesprint(pi) # 3.105828541230249
2.割圆法计算圆周率(思政,中华文明,精益求精)

import mathdef 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 / 2return piif __name__ == '__main__':print(cutting_circle(2)) # 3.1326286132812378print(cutting_circle(20)) # 3.141592653589663
3.莱布尼茨级数计算圆周率
数学思维
def leibniz_of_pi(error):"""接收用户输入的浮点数阈值为参数,用格雷戈里-莱布尼茨级数计算圆周率,返回圆周率值"""n, quarter_of_pi, sign = 1, 0, 1while 1 / (2 * n - 1) > error:quarter_of_pi = quarter_of_pi + sign * 1 / (2 * n - 1)n = n + 1sign = -signpi = 4 * quarter_of_pireturn piif __name__ == '__main__':print(leibniz_of_pi(1e-6)) # 3.141590653589692
4.蒙特卡洛法计算圆周率
统计方法,蒙特卡洛算法
import randomdef monte_carlo_pi(num):"""接收一个表示随机次数的整数,用蒙特卡洛法计算圆周率,返回一个浮点数"""hits = 0 # 落在圆内的计数器初值设为 0for 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 + 1pi = 4 * (hits / num)return piif __name__ == '__main__':print(monte_carlo_pi(1000000)) # 3.142968
5.梅钦级数计算圆周率
数学思维,效率意识
import mathdef machin_of_pi():"""用梅钦级数计算圆周率,返回圆周率值"""quarter_of_pi = 4 * math.atan(1/5) - math.atan(1/239)pi = 4 * quarter_of_pireturn piif __name__ == '__main__':print(machin_of_pi()) # 3.1415926535897936
6.拉马努金公式计算圆周率
数学思维,效率意识,循环在数学中的应用
import mathdef ramanujan_of_pi(n):"""接收一个正整数n为参数,用拉马努金公式的前n项计算圆周率并返回。"""result = 0for 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)) / 9801pi = 1 / resultreturn piif __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 / 2return pi
8.matplotlib演示蒙特卡洛
import matplotlib.pyplot as pltdef 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] # 落在圆内的点的列表xy_in_circle = [x[1] for x in in_circle_lst] # 落在圆内的点的列表yx_out_circle = [x[0] for x in out_circle_lst] # 落在圆外的点的列表xy_out_circle = [x[1] for x in out_circle_lst] # 落在圆外的点的列表yplt.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 # 落在圆内的计数器初值设为 0for 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 + 1turtle.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() # 结束绘制
