蒙特卡洛仿真的基于Python实例

article/2025/4/22 1:11:02
  • 文章原作者:新缸中之脑
  • 文章链接:https://www.toutiao.com/i7028498316396839432/?tt_from=weixin&utm_campaign=client_share&wxshare_count=1&timestamp=1638613017&app=news_article&utm_source=weixin&utm_medium=toutiao_ios&use_new_style=1&req_id=2021120418165701015015608914163D60&share_token=01C2E436-7124-40A6-B871-E04C0656CE78&group_id=7028498316396839432

蒙特卡洛仿真(或概率仿真)是一种用于了解金融部门风险和不确定性、项目管理、成本和其他预测机器学习模型的影响的技术。

风险分析是我们做出的几乎每一个决定的一部分,因为我们经常面临生活中的不确定性、模糊性和多变性。此外,即使我们获得了前所未有的信息,我们也不能准确预测未来。

蒙特卡洛仿真使我们能够看到所有可能的结果,并评估风险影响,从而允许在不确定性下更好的决策。

在本文中,我们将通过五个不同的示例来理解蒙特卡洛仿真方法。本教程的代码可在Github及Google Colab 找到。

1、 掷硬币翻转示例

掷一个无偏硬币的正面向上的概率为 1/2。然而,我们有什么办法可以实验证明吗?在此示例中,我们将使用蒙特卡洛方法模拟掷硬币 5000 次,以找出为什么正面向上的概率始终为 1/2。如果我们重复掷这个硬币很多很多次,那么可以达到更高的准确性。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UaBiRxUy-1638621844569)(attachment:image.png)]

## 导入库
import random 
import numpy as np
import matplotlib.pyplot as plt
## 投硬币的函数
def coin_filp():return random.randint(0,1) # 产生01随机数
## Monte Carlo Simulationprob_list1 = [] # 空列表存储概率值def monte_carlo(n):"""n 是模拟次数"""results = 0for i in range(n):flip_result = coin_filp()results =results + flip_result# Calculating probability valueprob_value = results/(i+1)# append the probability values to the listprob_list1.append(prob_value)# plot the resultsplt.axhline(y = 0.5,color = 'red',linestyle='-')plt.xlabel('Iterations')plt.ylabel('Probability')plt.plot(prob_list1)return results/n
# calling the functionanswer = monte_carlo(5000)
print('Final value:',answer)
Final value: 0.4968

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nsZEWzXM-1638621844572)(output_8_1.png)]

如上图所示,我们在 5000 次迭代后,获得正面向上的概率为 0.502。因此,这就是我们如何使用蒙特卡洛仿真来找到概率值的实验。

2.估计Π(pi)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8hBRHtZQ-1638621844573)(attachment:image.png)]

要估计 PI 的价值,我们需要正方型和圆的面积。为了找到这些区域,我们将随机将点放在表面上,并计算落在圆圈内的点和落在正方形内的点。这将给我们估计他们的面积。因此,我们将使用点计数作为区域,而不是使用实际区域的大小。

## 导入库
import turtle
import random
import matplotlib.pyplot as plt
import math
## 绘制点
# to visualize the random points
mypen = turtle.Turtle()
mypen.hideturtle()
mypen.speed(0)# drawing a square
mypen.up()
mypen.setposition(-100,-100)
mypen.down()
mypen.fd(200)
mypen.left(90)
mypen.fd(200)
mypen.left(90)
mypen.fd(200)
mypen.left(90)
mypen.fd(200)
mypen.left(90)# drawing a circle
mypen.up()
mypen.setposition(0,-100)
mypen.down()
mypen.circle(100)
# 初始化数据
# to count the points inside and outside the circle
in_circle = 0
out_circle = 0# to store the values of the PI
pi_values = []
# 主函数
# running for 5 times 
for i in range(5):for j in range(50):# generate random numbers x = random.randrange(-100,100)y = random.randrange(-100,100)# check if the number lies outside the circleif (x**2+y**2>100**2):mypen.color('black')mypen.up()mypen.goto(x,y)mypen.down()mypen.dot()out_circle = out_circle + 1else:mypen.color('red')mypen.up()mypen.goto(x,y)mypen.down()mypen.dot()in_circle = in_circle + 1# calculating the value of PIpi = 4.0 * in_circle/(in_circle + out_circle)# append the values of PI in listpi_values.append(pi)# Calculating the errorsavg_pi_errors = [abs(math.pi - pi) for pi in pi_values]# Print the final values of PI for each iterationsprint(pi_values[-1])
3.12
2.96
2.8533333333333335
3.0
3.04
# 绘制图像
# Plot the PI values
plt.axhline(y=math.pi,color='g',linestyle='-')
plt.plot(pi_values)
plt.xlabel('Iterations')
plt.ylabel('Values of PI')
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QpdTpzDy-1638621844574)(output_17_0.png)]

plt.axhline(y = 0.0,color = 'g',linestyle='-')
plt.plot(avg_pi_errors)
plt.xlabel('Iterations')
plt.ylabel('Error')
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N6Xlw2FA-1638621844575)(output_18_0.png)]

3.Monty Hall问题

假设在一个游戏节目中, 你可以选择三扇门之一: 一扇门后面是一辆车; 其他门后面都是山羊。你挑一扇门,比方说门1,主持人,他知道门后面是什么,打开另一扇门,比如说门3,有一只山羊。主持人然后问你:你是要坚持你的选择还是选择另一扇门?

换门对你有利吗?

根据概率,换门对我们是有利的。让我们了解一下:

最初,对于所有三个门,获得汽车的概率(P)是相同的(P = 1/3)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AtEQbJO8-1638621844576)(attachment:image.png)]

现在假设参赛者选择门 1。然后主持人打开第三扇门,门后面有一只山羊。接下来,主持人问参赛者是否想换门?

我们将看到为什么换门更有利:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QLnyZwCU-1638621844577)(attachment:image.png)]

在上图中,我们可以看到,在主持人打开3号门后,两扇门拥有汽车的概率增加到2/3。现在我们知道第三扇门有山羊,第二扇门有车的概率增加到2/3。因此,换门更有利。

## 导入库
import random
import matplotlib.pyplot as plt
## 初始化数据
# 1 = car
# 2 = goat
doors = ['goat','goat','car']switch_win_probability = []
stick_win_probability = []plt.axhline(y = 0.66666,color = 'r',linestyle='-')
plt.axhline(y = 0.33333,color = 'g',linestyle='-')
<matplotlib.lines.Line2D at 0x205f5578648>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4FbFNNi2-1638621844579)(output_29_1.png)]

import random
import matplotlib.pyplot as plt
## 初始化数据
# 1 = car
# 2 = goat
doors = ['goat','goat','car']switch_win_probability = []
stick_win_probability = []# monte carlo simulationdef monte_carlo(n):# calculating switch and stick wins:switch_wins = 0stick_wins = 0for i in range(n):# randomly placing the car and goats behind three doorsrandom.shuffle(doors)# contestant's choicek = random.randrange(2)# If the contestant doesn't get carif doors[k] != 'car':switch_wins += 1else:stick_wins += 1# updatating the list valuesswitch_win_probability.append(switch_wins/(i+1))stick_win_probability.append(stick_wins/(i+1))# plotting the dataplt.plot(switch_win_probability)plt.plot(stick_win_probability)# print the probability valuesprint('Winning probability if you always switch',switch_win_probability[-1])print('Winning probability if you always stick to your original choice:',stick_win_probability[-1])

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q0oAMCrF-1638621844579)(output_30_0.png)]

monte_carlo(1000)
plt.axhline(y = 0.66666,color = 'r',linestyle='-')
plt.axhline(y = 0.33333,color = 'g',linestyle='-')
Winning probability if you always switch 0.655
Winning probability if you always stick to your original choice: 0.345<matplotlib.lines.Line2D at 0x205f40976c8>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PskZXqcI-1638621844580)(output_31_2.png)]

4、Buffon’s Needle问题

法国贵族Buffon,在1777年发布了以下问题:

假设我们在一张划线纸上扔一根短针——针头正好跨越线的位置的可能性是多大?

概率取决于纸上线条之间的距离(d),也取决于我们扔的针的长度(l),或者更确切地说,这取决于比率l/d。对于这个例子,我们可以认为针l ≤ d。简言之,我们的目的是假设针不能同时跨越两条不同的线。令人惊讶的是,这个问题的答案涉及PI。

import random
import matplotlib.pyplot as plt
import math
def monte_carlo(runs,needles,n_lenth,b_width):# Empty list to store pi values:pi_values = []# Horizontal line  for actual value of PIplt.axhline(y=math.pi,color = 'r',linestyle='-')# For all runs:for i in range(runs):# Initialize number of hits as 0nhits = 0# For all needlesfor j in range(needles):# We will find the distance from the nearest vertical line# min = 0,max = b_width/2x = random.uniform(0,b_width/2.0)# The theta value will be from 0 to pi/2theta = random.uniform(0,math.pi/2)# checking if the needle crosses the line or notxtip = x - (n_lenth/2.0)*math.cos(theta)if xtip < 0 :nhits += 1# Going with the formulanumerator = 2.0 * n_lenth * needlesdenominator = b_width * nhits# Append the final value of pipi_values.append((numerator/denominator))# Final pi value after all iterationsprint(pi_values[-1])# Plotting the graph:plt.plot(pi_values)
# Total number of runs
runs = 100
# Total number of needles
needles = 100000
# Length of needle
n_lenth = 2
# space between 2 verical lines
b_width = 2
# Calling the main function
monte_carlo(runs,needles,n_lenth,b_width)
3.153728495513821

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rOvKCYc0-1638621844581)(output_38_1.png)]

5、为什么庄家总是赢?

赌场如何赚钱?诀窍很简单 —— "你玩得越多, 赌场赚得越多。让我们通过一个简单的蒙特卡洛模拟示例来看看其运作原理。

考虑一个假想的游戏,玩家必须从一袋芯片中挑一个芯片。

规则:

  • 袋子里装着1~100个芯片。
  • 用户可以投注芯片数量为偶数或奇数。
  • 在这个游戏中,10和11是特殊数字。如果我们押注于偶数,则 10 将计为奇数,如果我们押注奇数,则 11 将计为偶数。
  • 如果我们押注偶数, 我们得到 10, 那么我们输了。
  • 如果我们押注奇数, 我们得到 11, 那么我们输了。

如果我们押注奇数,我们获胜的概率为49/100。庄家获胜的概率是51/100。因此,对于一个奇数赌注,庄家的利润是 = 51/100- 49/100 = 200/10000 = 0.02 = 2%

如果我们押注于偶数,用户获胜的概率为 49/100。庄家获胜的概率是51/100。因此,对于一个偶数赌注,庄家的利润是 = 51/100-49/100 = 200/10000 = 0.02 = 2%

总之,每下1美元的赌注,其中0.02美元就归庄家的。相比之下,轮盘赌庄家的最低利润为2.5%。因此,我们确信,在假想的比赛中,你比轮盘赌更有可能获胜。

import random
import matplotlib.pyplot as plt# Place your bet:
# User can choose even or odd number
choice = input("Don you want to bet on Even number or odd number\n")# For even
if choice =='Even':def pickNote():# get random number between 1-100note = random.randint(1,100)# check for our game conditions# Notice that 10 isn't considered as even numberif note%2 != 0 or note == 10:return Falseelif note%2 ==0:return True# For odd
elif choice =='Odd':def pickNote():# get random number between 1-100note = random.randint(1,100)# check for our game conditions# Notice that 10 isn't considered as even numberif note%2 == 0 or note == 11:return Falseelif note%2 == 1:return True
Don you want to bet on Even number or odd number
Odd
# Main function 
def play(total_money ,bet_money,total_plays):num_of_plays = []money = []# start with play number 1play = 1for play in range(total_plays):# Winif pickNote():# Add the money to our fundstotal_money = total_money + bet_money# append the play numbernum_of_plays.append(play)# append the new fund amoutmoney.append(total_money)# Loseif pickNote():# Add the money to our fundstotal_money = total_money - bet_money# append the play numbernum_of_plays.append(play)# append the new fund amoutmoney.append(total_money)# Plot the dataplt.ylabel('Player Money in $')plt.xlabel('Number of bets')plt.plot(num_of_plays,money)final_funds = []# Final values after all the iterationsfinal_funds.append(money[-1])return( final_funds)
 # Run 10 time# 修改这里的次数
for i in range(1000):ending_fund = play(10000,100,50)
print(ending_fund)
print(sum(ending_fund))# print the money the player ends with
print('The player started with $10,000')
print('The player left with $',str(sum(ending_fund)/len(ending_fund)))
[10400]
10400
The player started with $10,000
The player left with $ 10400.0

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W47CL8yk-1638621844582)(output_46_1.png)]


http://chatgpt.dhexx.cn/article/hYV1hpSP.shtml

相关文章

检测性能的蒙特卡洛仿真-检测部分

一、 实验目的 使用matlab编程&#xff0c;利用蒙特卡洛方法&#xff0c;对一个简单的二元假设检验问题进行仿真&#xff0c;分析不同信噪比下检测器的性能。 二、 实验步骤 通过蒙特卡洛仿真实验&#xff0c;检测性能在不同信噪比下的表现&#xff0c;以验证信噪比对于检测…

5G仿真-蒙特卡洛仿真方法

5G仿真-蒙特卡洛仿真方法 #蒙特卡洛仿真法 蒙特卡洛方法也称为统计试验方法&#xff0c;它是采用统计的抽样理论来近似求解数学问题或物 理问题&#xff0c;它即可以求解概率问题&#xff0c;也可以求解非概率问题&#xff0c;蒙特卡洛方法是系统模拟的重要方法。下面举例说明…

talemu---蒙特卡洛仿真软件产品介绍

一 简介 talemu是拥有独立知识产权的国产软件&#xff0c;核心功能是进行蒙特卡洛仿真。通过应用多项自研成果&#xff0c;能够对主流开发语言编写的模型自动创建蒙特卡洛仿真模型&#xff0c;还能够对依赖特定软硬件环境的模型创建仿真模型。依据模型自动生成仿真数据并完成蒙…

蒙特卡罗仿真(1):入门求生指南(Python实例)

目录 1. 前言 1.1 两个要点 1.2 Simulation pros and con’s[2] 2. 随机数生成 3. 几个简单的应用 3.1 抛硬币实验 3.2 扔骰子实验 3.3 用蒙特卡罗仿真求pi值 3.4 估计定积分的值​​​​​​​ 4. 小结 1. 前言 仿真&#xff08;Simulation&#xff09;&#xff1a;…

武器系统仿真技术(二):末端制导系统蒙特卡洛仿真法

1.蒙特卡洛仿真方法的统计特性 假设一个 m m m个系统输出数据 { y i } i 1 m \{y_i\}_{i1}^m {yi​}i1m​&#xff0c; N N N次循环得到 N N N组数据 { { y i } i 1 m } j 1 N \{\{y_i\}_{i1}^m\}_{j1}^N {{yi​}i1m​}j1N​。那么实际上会有以下两组统计特性指标: 1.2数值…

检测性能的蒙特卡洛仿真-估计部分

一、 实验目的 使用matlab编程&#xff0c;利用蒙特卡洛方法&#xff0c;对一个简单的二元假设检验问题进行仿真&#xff0c;分析不同信噪比下检测器的性能&#xff0c;分析SNR、MSE对估计的影响。 二、 实验步骤 通过蒙特卡洛仿真实验&#xff0c;检测性能在不同信噪比下的…

cadence的工艺角仿真、蒙特卡洛仿真、PSRR

cadence的工艺角仿真、蒙特卡洛仿真、PSRR 工艺角仿真打开ADE XL选择工艺角为ff设置工艺角 蒙特卡洛仿真PSRR温度扫描 学习来源&#xff1a;https://www.bilibili.com/video/BV1gX4y1g7JJ?spm_id_from333.337.search-card.all.click 工艺角仿真 打开ADE XL 当你在ADEL完成仿…

雅可比迭代法法

雅可比迭代法法 在图形图像中很多地方用到求矩阵的特征值和特征向量&#xff0c;比如主成分分析、OBB包围盒等。编程时一般都是用数值分析的方法来计算&#xff0c;这里介绍一下雅可比迭代法求解特征值和特征向量。雅可比迭代法的原理&#xff0c;网上资料很多&#xff0c;详细…

雅可比迭代法和高斯赛德尔迭代法

刚学 Jacobi算法和Gauss_Siedel算法不久&#xff0c;觉的对以后学习会有帮助&#xff0c;所以记下来&#xff0c;希望感兴趣的朋友共勉&#xff01; 雅克比迭代 #include < iostream > #include " math.h " using namespace std; #define n 3 double a[n][n] …

数值计算——雅可比迭代法解线性方程组

1.雅克比迭代法的计算过程: (1).取初始向量: &#xff08;1&#xff09; (2).迭代过程 &#xff08;2&#xff09; 2.求解实例&#xff1a; &#xff08;3&#xff09; 用 Jacobi 方法求解&#xff0c;精确到小数点后 6 位, 给出所需步数及残差; 3.求解结果&#xff1a; 当n1…

雅可比迭代法、高斯-赛德尔迭代法、超松弛迭代法 matlab 实现

雅可比迭代法、高斯-赛德尔迭代法、超松弛迭代法 matlab 实现 一、雅可比迭代法 程序代码&#xff1a; function y Jacobi(A,b,e,M) % input: A 的对角线元素均不为 0 e: 精度 M: 最大计算次数 % output: y: 方程的解n length(A); x0 zeros(n,1); y zeros(n,1);[l,w] si…

数值计算——雅可比迭代法解线性方程组(附代码)

1.雅克比迭代法的计算过程: (1).取初始向量: &#xff08;1&#xff09; (2).迭代过程 &#xff08;2&#xff09; 2.求解实例&#xff1a; &#xff08;3&#xff09; 用 Jacobi 方法求解&#xff0c;精确到小数点后 6 位, 给出所需步数及残差; 3.求解结果&#xff1a; 当n1…

雅可比迭代法程序c语言,求雅可比迭代法解方程组的C\C++程序

满意答案 singleycf 2013.07.05 采纳率&#xff1a;54% 等级&#xff1a;13 已帮助&#xff1a;7908人 #include #include Jacobidiedai(int n, double *a, double *b,double *x) { int i,j; double *x0,m0,eps; x0 (double *) malloc(n*sizeof(double)); for(i0;i x0[i]x…

雅可比迭代法解线性方程组。

L U分解在我之前写的文章里。 定义的变量有点多&#xff0c;但挺容易看的。 #include<stdio.h> #include<math.h> #define N 3 int main (void) {double A[N][N] {0};double D[N][N] {0};double L[N][N] {0};double U[N][N] {0};double C[N][N] {0};double…

线性方程组迭代法—雅克比迭代法C++

此例子使用三个变量、三个方程的情况&#xff0c;如需讨论多个的情况&#xff0c;使用vector稍加修改即可。 使用的方程组如下&#xff1a; 每次迭代的值如下&#xff1a; 程序流程图&#xff1a; 程序代码&#xff1a; /********雅克比迭代法********* *1.Xi为每一步迭代…

《数值分析》-- 雅可比迭代法、高斯—塞德尔迭代法

文章目录 一、基本迭代法的格式及收敛性1.1 迭代法思想1.2 向量序列收敛的定义 二、迭代法的收敛与发散三、雅可比迭代法和高斯赛德尔迭代法3.1 雅可比迭代法3.2 高斯――赛得尔(Gauss-Seidel)迭代法 四、迭代法的收敛性4.1 严格对角占优矩阵与对角占优矩阵4.2 Jacobi迭代法和G…

雅克比迭代法,高斯赛德尔迭代法,sor迭代法(python)

计算方法实验&#xff0c;在已给matlab的程序基础上进行修改得到的python程序&#xff0c;原理不再赘述。实际使用时&#xff0c;只需修改以下程序中的A,b矩阵&#xff08;注意只适用与A为n*n的情况&#xff09; 1.雅克比迭代法 import numpy as npA np.array([[10,-1,-2],[…

C语言实现雅克比迭代法求根

C语言实现雅克比迭代法求根 雅克比迭代法求根 C语言实现雅克比迭代法求根问题描述算法思想C语言程序实验结果 问题描述 设方程组 A x b Ax b Axb的系数矩阵 A A A非奇异 &#xff0c;且 a i i ≠ 0 {a_{ii}} \ne 0 aii​​0将 A A A分裂为&#xff1a; A D L U A D L…

雅克比迭代法和高斯-塞德尔迭代法

https://wenku.baidu.com/view/ac6a0d89d0d233d4b04e6905.html 另外附上迭代收敛的条件&#xff1a; 且越小&#xff0c;收敛的越快。

雅可比迭代法

雅可比迭代法 设有线性方程组 &#xff08;1&#xff09; 其矩阵形式为 设系数矩阵A为非奇异矩阵&#xff0c;且 从式(1)的第个方程中解出&#xff0c;得其等价形式 (2) 取初始向量 对式(2)应用迭代法&#xff0c;建立相应的迭代公式 (3) 也可记为矩阵形式 (4) 若将系数…