楼主: huiyujuanjuan
2947 2

[程序分享] 蒙特卡罗模拟圆周率,不同方法运算速度对比 [推广有奖]

  • 0关注
  • 6粉丝

已卖:47份资源

副教授

37%

还不是VIP/贵宾

-

威望
0
论坛币
651 个
通用积分
330.7491
学术水平
19 点
热心指数
23 点
信用等级
10 点
经验
46752 点
帖子
500
精华
0
在线时间
1160 小时
注册时间
2015-2-2
最后登录
2025-11-9

楼主
huiyujuanjuan 发表于 2019-9-8 09:14:17 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

      蒙特卡罗模拟又称统计模拟法、随机抽样技术,是一种随机模拟方法,具体使用随机数(或更常见的伪随机数)来解决很多计算问题的方法。将所求解的问题同一定的概率模型相联系,用电子计算机实现统计模拟或抽样,以获得问题的近似解。

蒙特卡罗方法于20世纪40年代美国在第二次世界大战中研制原子弹的“曼哈顿计划”计划的成员S.M.乌拉姆和J.冯·诺伊曼首先提出。数学家冯·诺伊曼用驰名世界的赌城—摩纳哥的Monte Carlo—来命名这种方法,为它蒙上了一层神秘色彩。其实在这之前,蒙特卡罗方法就已经存在。1777年,法国Buffon提出用投针实验的方法求圆周率。这被认为是蒙特卡罗方法的起源。

       由概率定义知,某事件的概率可以用大量试验中该事件发生的频率来估算。因此,可以先对影响其可靠度的随机变量进行大量的随机抽样,然后把这些抽样值一组一组地代入功能函数式,确定结构是否失效,最后从中求得结构的失效概率。蒙特卡罗法正是基于此思路进行分析的。

QQ图片20190908090324.png


1.1 积分模拟计算

QQ图片20190908090429.png

      利用蒙特卡罗模拟方法,原理比较简单,首先生成需要计算的函数:>f <- function(x) exp(x^2)然后进行计算,考虑到积分计算近似于N个正方形相加,每个正方形的长度为exp(xi),宽度为1/N,面积为exp(xi)* 1/N,再把每个面积加总,即为函数的平均值,命令为:> mean(f(x))[1] 1.462684毫无疑问,一些积分得不到解析式结果的话,利用这种方法计算会非常方便。

1.2 圆周率计算

QQ图片20190908090536.png


aaa.png



                                                                        图2.39    随机模拟圆周率

        计算下面自建一个函数calpi,用于计算圆周率pi。具体如下:

>calpi <- function(n){

>  count <- 0

>  for( i in 1:n){

#用循环进行计算

>    x <- runif(1,0,1)   #产生均匀分布随机数

>    y <- runif(1,0,1)   #产生均匀分布随机数

>    if (x^2 +y^2 <= 1 )

>      count <- count+1 } #判断点是否位于圆内

>  return(4*count/n) } #返回计算结果

在此基础上运用10000随机数,得到的结果为:

>calpi(10000)

[1] 3.1644

精度不算高,进一步提高随机数的数量,令为10000000,但需要花较长的时间,并计算所花的时间,对应命令为:

>t0 <- Sys.time()

>calpi(10000000)[1] 3.141121

>t1 <- Sys.time()

>t1-t0

Time difference of25.51678 secs   

   精度在大幅提高,但时间为25秒,相对较长。因此,需要进一步提高软件的运行效率。一般而言,为了提高R语言的运行效率,尽量采用以下原则:

   第一、避免循环,采用向量化方法进行分析,如常用的for改成apply等函数进行分析,或者利用内置函数rowSums等避免循环;

   第二、预先给对象分配内存,且减少cbindrbind等函数的使用;

   第三、运用并行计算工具包,如parallelforeach等工具包进行分析。

  基于此,下面对代码进行优化,提高运行效率,把循环变成矩阵形式,并进一步利用rowSums函数筛选出 上面红色的点,同时计算运行时间,具体如下:

>N <- 100000000

>t0 <- Sys.time()

>x <- matrix(runif(2 * N), ncol = 2)

>4*mean(rowSums(x^2)<=1) [1] 3.141599

>t1 <- Sys.time()

>t1-t0

Time difference of11.34028 secs

可以看出,利用矩阵、内置函数rowSumsmean,使运行效率大幅提高,时间从25.5秒下降到11.3秒,几乎缩短一半。

        感兴趣的读者可进一步参考《量化投资基础、方法与策略——R语言实战指南》,里面详细介绍R语言的入门,并介绍如何利用R语言进行量化投资。

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝


已有 1 人评分论坛币 收起 理由
cheetahfly + 30 精彩帖子

总评分: 论坛币 + 30   查看全部评分

本帖被以下文库推荐

沙发
cheetahfly 在职认证  发表于 2019-9-10 12:17:17
谢谢分享

藤椅
齐物论pi 学生认证  发表于 2019-9-12 07:56:56 来自手机
rcpp封装了C++更快

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2026-2-7 20:32