版权声明:本文为博主原创文章,未经博主允许不得转载。
文章目录
一、理论基础
1.1 概念
1.2 基本原理
1.3 π 的计算
1.4 积分的计算
1.5 举例
1.5.1 财富分配
1.5.2 婚恋配对
1.5.3 厕所排队
二、代码实现
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
# 步骤一(替换sans-serif字体)
plt.rcParams['font.sans-serif'] = ['SimHei']
# 步骤二(解决坐标轴负数的负号显示问题
plt.rcParams['axes.unicode_minus'] = False
2.3 π 的计算
n = 10000
r = 1.0
a, b = 0.0, 0.0
xmin, xmax = a - r, a + r
ymin, ymax = b - r, b + r
# 均匀生成介于xmin和xmax的 n 个值
x = np.random.uniform(xmin, xmax, n)
y = np.random.uniform(ymin, ymax, n)
fig = plt.figure(figsize = (8, 8))
ax = fig.add_subplot(111)
# 散点图,也即plt.scatter(x,y,s=1)
plt.plot(x, y, 'ro',markersize = 1)
plt.axis('equal')
from matplotlib.patches import Circle
# xy表示圆心位置,radius 表示半径
circle = Circle(xy = (a, b), radius=r, color = 'gray', alpha = 0.6)
ax.add_patch(circle)
# 求点到圆心的距离
d = np.sqrt((x-a)**2 + (y-b)**2)
# 落在圆内的点的个数
m = len(d[d<r])
# 圆的面积/正方形面积=π*(r**2)/(2r)**2 = π/4 = 圆内的点的个数/总个数 = m/n
π = 4 * m / n
print(π)
运行结果
3.1528
2.4 积分的计算:y = x**2
n = 10000
# 矩形x轴边界
xmin, xmax = 0, 1.0
# 矩形y轴边界
ymin, ymax = 0, 1.0
x = np.random.uniform(xmin, xmax, n)
y = np.random.uniform(ymin, ymax, n)
fig = plt.figure(figsize = (8, 8))
ax = fig.add_subplot(111)
# 在矩形内随机投点
plt.scatter(x, y, s = 0.6)
plt.xlim([0, 1])
plt.ylim([0, 1])
xi = np.linspace(0, 1, 100)
yi = xi ** 2
# 绘制 y = x**2 曲线
plt.plot(xi, yi, linestyle = '--', color = 'red')
# 填充 y<x**2 部分
plt.fill_between(xi, yi, 0, color = 'gray', alpha = 0.6)
# 求落在阴影部分的点的个数
m = len(d[y < x ** 2])
# 阴影部分点的个数 / 总个数
integral = m / n
print(integral)
运行结果
0.3376
2.5 举例
2.5.3 厕所排队
- 1. 两场电影结束时间相隔较长,互不影响;
- 2. 每场电影结束之后会有20个人想上厕所;
- 3. 这 20 个人会在0到10分钟之内全部到达厕所
- 4. 每个人上厕所时间在1-3分钟之间
- 首先模拟最简单的情况,也就是厕所只有一个位置,不考虑两人共用的情况则每人必须等上一人出恭完毕方可进行。
- 分析:对于每个人都有几个参数:到达时间 / 等待时间 / 开始上厕所时间 / 上厕所时间 / 结束时间
# 到达时间
arrivingtime = np.random.uniform(0,10,20)
# 排序
arrivingtime.sort()
# 上厕所时间
workingtime = np.random.uniform(0, 3, 20)
# 开始时间
startingtime = [0 for i in range(20)]
# 等待时间
waitingtime = [0 for i in range(20)]
# 完成时间
finishingtime = [0 for i in range(20)]
# 厕所空闲时间
emptytime = [0 for i in range(20)]
# 第一个人开始时间等于到达时间
startingtime[0] = arrivingtime[0]
# 第一个人结束时间等于 开始时间 + 上厕所时间
finishingtime[0] = startingtime[0] + workingtime[0]
# 第一个人的等待时间
waitingtime[0] = startingtime[0] - arrivingtime[0]
print('到达时间 等待时间 开始上厕所时间 工作时间 结束时间 厕所空闲时间 :')
print(arrivingtime[0], waitingtime[0], startingtime[0], workingtime[0], finishingtime[0], emptytime[0])
for i in range(len(arrivingtime)-1):
# 如果某个人到达,上一个人尚未结束,则这个人的开始时间为上一个人的结束时间
if arrivingtime[i+1] <= finishingtime[i]:
startingtime[i+1] = finishingtime[i]
emptytime[i] = 0
else:
emptytime[i] = arrivingtime[i+1] - finishingtime[i]
# 如果某个人到达,上一个人已结束,则这个人的开始时间即为他的到达时间
startingtime[i+1] = arrivingtime[i+1]
waitingtime[i+1] = startingtime[i+1] - arrivingtime[i+1]
finishingtime[i+1] = startingtime[i+1] + workingtime[i+1]
for i in range(len(arrivingtime)):
print('第 %d 个人:到达时间:%.5f, 等到时间:%.5f, 开始上厕所时间:%.5f, 上厕所时间:%.5f, 完成时间:%.5f, 厕所空闲时间:%.5f'
%(i, arrivingtime[i], waitingtime[i], startingtime[i], workingtime[i], finishingtime[i], emptytime[i]))
print('平均等待时间:', np.mean(waitingtime))
fig = plt.figure(figsize = (10, 4))
plt.plot(waitingtime, '-go')
plt.grid(True, linestyle = '--', color = 'gray', linewidth = '0.8')
plt.title('蒙特卡罗模拟 - 排队上厕所问题')
运行结果
到达时间 等待时间 开始上厕所时间 工作时间 结束时间 厕所空闲时间 :
0.28956489922632556 0.0 0.28956489922632556 1.4310131825208445 1.72057808174717 0
第 0 个人:到达时间:0.28956, 等到时间:0.00000, 开始上厕所时间:0.28956, 上厕所时间:1.43101, 完成时间:1.72058, 厕所空闲时间:0.00000
第 1 个人:到达时间:0.34842, 等到时间:1.37216, 开始上厕所时间:1.72058, 上厕所时间:2.04697, 完成时间:3.76755, 厕所空闲时间:0.00000
第 2 个人:到达时间:1.04983, 等到时间:2.71772, 开始上厕所时间:3.76755, 上厕所时间:2.72089, 完成时间:6.48845, 厕所空闲时间:0.00000
第 3 个人:到达时间:1.28277, 等到时间:5.20568, 开始上厕所时间:6.48845, 上厕所时间:2.04596, 完成时间:8.53440, 厕所空闲时间:0.00000
第 4 个人:到达时间:2.24144, 等到时间:6.29296, 开始上厕所时间:8.53440, 上厕所时间:0.54923, 完成时间:9.08363, 厕所空闲时间:0.00000
第 5 个人:到达时间:2.51428, 等到时间:6.56935, 开始上厕所时间:9.08363, 上厕所时间:0.00223, 完成时间:9.08586, 厕所空闲时间:0.00000
第 6 个人:到达时间:2.60195, 等到时间:6.48391, 开始上厕所时间:9.08586, 上厕所时间:0.84290, 完成时间:9.92876, 厕所空闲时间:0.00000
第 7 个人:到达时间:2.76601, 等到时间:7.16275, 开始上厕所时间:9.92876, 上厕所时间:0.15394, 完成时间:10.08270, 厕所空闲时间:0.00000
第 8 个人:到达时间:3.52302, 等到时间:6.55969, 开始上厕所时间:10.08270, 上厕所时间:0.43085, 完成时间:10.51355, 厕所空闲时间:0.00000
第 9 个人:到达时间:3.61336, 等到时间:6.90019, 开始上厕所时间:10.51355, 上厕所时间:1.84115, 完成时间:12.35470, 厕所空闲时间:0.00000
第 10 个人:到达时间:3.83702, 等到时间:8.51768, 开始上厕所时间:12.35470, 上厕所时间:0.11996, 完成时间:12.47465, 厕所空闲时间:0.00000
第 11 个人:到达时间:3.90128, 等到时间:8.57338, 开始上厕所时间:12.47465, 上厕所时间:1.33500, 完成时间:13.80965, 厕所空闲时间:0.00000
第 12 个人:到达时间:4.86442, 等到时间:8.94523, 开始上厕所时间:13.80965, 上厕所时间:1.85913, 完成时间:15.66878, 厕所空闲时间:0.00000
第 13 个人:到达时间:5.18039, 等到时间:10.48840, 开始上厕所时间:15.66878, 上厕所时间:2.30958, 完成时间:17.97836, 厕所空闲时间:0.00000
第 14 个人:到达时间:6.39401, 等到时间:11.58435, 开始上厕所时间:17.97836, 上厕所时间:2.90727, 完成时间:20.88564, 厕所空闲时间:0.00000
第 15 个人:到达时间:8.00359, 等到时间:12.88204, 开始上厕所时间:20.88564, 上厕所时间:2.38811, 完成时间:23.27375, 厕所空闲时间:0.00000
第 16 个人:到达时间:8.37526, 等到时间:14.89849, 开始上厕所时间:23.27375, 上厕所时间:0.86462, 完成时间:24.13837, 厕所空闲时间:0.00000
第 17 个人:到达时间:8.76109, 等到时间:15.37728, 开始上厕所时间:24.13837, 上厕所时间:1.02543, 完成时间:25.16380, 厕所空闲时间:0.00000
第 18 个人:到达时间:8.94116, 等到时间:16.22264, 开始上厕所时间:25.16380, 上厕所时间:1.28243, 完成时间:26.44623, 厕所空闲时间:0.00000
第 19 个人:到达时间:9.60998, 等到时间:16.83625, 开始上厕所时间:26.44623, 上厕所时间:2.05967, 完成时间:28.50590, 厕所空闲时间:0.00000
平均等待时间: 8.67950669917162
版权声明:本文为博主原创文章,未经博主允许不得转载。