F#奇妙游(22):Monte Carlo方法的F#实现

news2025/1/11 7:14:15

一个小问题的求解

问题

一根 1m 长的玻璃棒,摔倒地上断成 3 段,最短一段的平均值是多少?

假设玻璃棒一定会摔成三段,且玻璃棒质地均匀,为理想状态。

物理的视角

玻璃棒摔成三段,其物理过程是什么样的?

有一位网友分析了倾斜碰撞的应力分布,提出了断裂位置的可能性分布,并把一次断成三阶分解为同时发生的两次物理上相似的断裂。

其实玻璃棒的断裂更可能是地面的冲击力导致的,而不是倾斜碰撞。这样的话,断裂位置的可能性分布就是均匀的,而不是倾斜的。这里的均匀意思是地面可能与玻璃棒接触(形成单点接触)的位置可能是导致断裂的原因,而不一定是一段倾斜碰撞带来的应力集中。

数学的视角

从数学的角度,忽略物理的过程,可以有不同的假设。

单纯考虑断裂为三段,因为题目中已经假设了必然断裂为三段,类似于剪刀剪断绳索的情况。那么这三段的长度分别为 x , y , z x, y, z x,y,z ,且有 x + y + z = 1 x + y + z = 1 x+y+z=1

很明显,三者的长度无法倍当作独立事件来考虑,最终只能定义为两个独立事件,也就是断裂的点(两个)考虑为独立事件。

两个断裂段的位置定义为 r 1 , r 2 r_1, r_2 r1,r2 ,则断裂的三段长度为:

x = min ⁡ i = 1 , 2 r i y = ∣ r 1 − r 2 ∣ z = 1 − max ⁡ i = 1 , 2 r i \begin{aligned} x &= \min_{i=1,2}r_i \\ y &= \left|r_1-r_2\right| \\ z &= 1 - \max_{i=1,2}r_i\\ \end{aligned} xyz=i=1,2minri=r1r2=1i=1,2maxri

其中 r i r_i ri 的概率密度函数为:

f ( r i ) = { 1 , 0 ≤ r i ≤ 1 0 , otherwise f(r_i) = \begin{cases} 1, & 0 \le r_i \le 1 \\ 0, & \text{otherwise} \end{cases} f(ri)={1,0,0ri1otherwise

蒙特卡洛模拟

蒙特卡洛模拟的思路是,随机生成 r 1 , r 2 r_1, r_2 r1,r2 ,计算 x , y , z x, y, z x,y,z ,然后计算 min ⁡ { x , y , z } \min \{x,y,z\} min{x,y,z} 的平均值。

open System
let r = Random(42)

let break2 () =
    let a = r.NextDouble()
    let b = r.NextDouble()     
    [min a b; abs (b-a); 1. - max a b]


let breakN n =
    seq {
        for _ in (bigint 1) .. n do
            yield break2 ()
    }

let minAverage n =
    breakN n
    |> Seq.map List.min
    |> Seq.average

for i in 1..7 do
    let n = 10. ** float i |> bigint
    printfn $"%4A{i} %20A{n} %12f{minAverage n}"

得到的结果:

1 10     0.129573
2 100     0.096320
3 1000     0.105467
4 10000     0.110859
5 100000     0.111424
6 1000000     0.111146
7 10000000     0.111107

接近某网友分析的 1 / 9 1/9 1/9

更广义的伪随机采样算法

上面这个问题,属于一类称为伪随机采样的计算方法。伪随机采样的思路是,随机生成一些数据,然后计算这些数据的某个统计量,这个统计量就是我们想要的结果。典型的问题就是上面的概率问题,也就是估计一阶统计量(平均值)。还有一类就是估计二阶统计量,比如方差。

求解问题的关键有两个部分:

  1. 自变量的统计分布和采样生成;
  2. 统计量的计算。

对于第一个问题,我们可以使用一些已知的分布,比如均匀分布、正态分布等等。也可以使用一些已知的采样方法,比如拒绝采样、重要性采样等等。

第二个问题一般包括了对物理过程的数学模型的计算,以及对采样数据的统计量计算。

除了对统计量的计算,Monte carlo方法还可以用于确定问题的转化计算,就是可以把一个物理量视为统计量或者统计量的函数。比如前面的 π \pi π 的计算问题,转化为面积的比值,也就是概率的比值。

一个典型的应用就是求解积分。上面的圆周率计算,实际上也就是求圆的面积,也就是求解积分。多重积分的Monte Carlo计算也是一个很常用的方法。

多重积分的计算

问题定义和算法

I = ∫ ∫ ∫ ⋯ ∫ f ( x ) d x I = \int\int\int\cdots\int f(\mathbf{x})d\mathbf{x} I=∫∫∫f(x)dx

形如上面的积分,当积分重数很大时,通过分步积分的方法很难求解。这时候可以使用Monte Carlo方法来求解。

求解过程也很简单,就是随机生成一些点,然后计算这些点的函数值的平均值,乘以积分区域的体积。

x ∈ ∏ i = 1 n [ a i , b i ] \mathbf{x} \in \prod_{i=1}^n [a_i, b_i] xi=1n[ai,bi]

其中, a i , b i a_i, b_i ai,bi 伪定义域的上下界。

I ^ N = ∫ ∫ ∫ ⋯ ∫ f ( x ) d x = ∏ i = 1 n ( b i − a i ) 1 N ∑ j = 1 N f ( x j ) \hat{I}_N = \int\int\int\cdots\int f(\mathbf{x})d\mathbf{x} = \prod_{i=1}^n (b_i - a_i) \frac{1}{N}\sum_{j=1}^N f(\mathbf{x}_j) I^N=∫∫∫f(x)dx=i=1n(biai)N1j=1Nf(xj)

这里 N N N 就是采样数目,随着 N N N 的增加,计算结果会越来越趋近真值。

I = I ^ N ∣ N → ∞ I = \hat{I}_{N} |_{N\to \infty} I=I^NN

F#代码示例

下面就用F#来实现一个多重积分的计算程序。

// Monte Carlo Integration
open System

// random float in [lb, ub]
let r = Random(42)
let rf (lb, ub) = r.NextDouble() * (ub - lb) + lb

// random sample in bounds
let sample (bounds: (float*float) array) =
    bounds
    |> Array.map rf

// volumn of bounds
let volumn (bounds: (float*float) array) = 
    bounds
    |> Array.map (fun (lb, ub) -> Math.Abs(ub - lb))
    |> Array.sum

// Monte Carlo Integration
let mc f (bounds: (float*float) array) N =
    [|1..N|]
    |> Array.map (fun _ -> sample bounds)  // sample N points
    |> Array.map f // f(x)
    |> Array.average // 1/N * sum(f(x))
    |> fun x -> x * (volumn bounds)

上面就是多重积分的全部代码,要求目标函数的参数是一个float array,返回值是一个float。积分上下限是一个float*float的元组数组。

下面是测试算法收敛性的代码,计算的采样数目是 2 N 2^N 2N N N N 从10到25。

// Test
let f (x: float array) =
    x
    |> Array.map (fun x -> x * x)
    |> Array.sum
let b = Array.init 10 (fun _ -> (-1.0, 1.0))

let Ns = [|10..25|] |> Array.map (fun i -> int(Math.Pow(2, i)))
let Ifs = Ns |> Array.map (mc f b)


利用ScottPlot绘制图像:


// Plot

#r "nuget: ScottPlot, 4.1.0"

open ScottPlot
let plt = Plot(600, 400)
plt.AddScatter(Ns |> Array.map float, Ifs)
plt.Title("Monte Carlo Integration convergence")
plt.XLabel("N")
plt.YLabel("I")
plt.SaveFig("img/mc.png")

在这里插入图片描述

可以很好的看到10重积分依然能做到很高的收敛精度。

这个算法也算是求解多重积分的一个很高效的方法了,相对于分步积分,这个方法的收敛速度更快,而且可以很容易的并行化。

结论

  1. F#编写数值算法代码非常方便,通过对数组进行函数式的操作,避免采用C和C++的for循环,算法的逻辑更加清晰,代码也更加简洁。
  2. Monte Carlo方法可以用于求解很多问题,比如求解积分、求解概率、求解物理量等等。其算法简单粗暴容易实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/917937.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VUE调用高德地图之电子围栏

最近项目上电子围栏功能,就是地图上限定的区域内实现限行功能,用我们身边的事物来举例,共享单车的限行、限停区域就是电子围栏。由此可见,电子围栏最基础的做法就是在地图上实现多边形覆盖物。 效果图大概如下: 照例,第一步:加载JS AP。 1.在public/index.html中加入…

【LINUX协议栈】netfilter之连接跟踪机制

1、什么是链接跟踪 连接跟踪,顾名思义,就是跟踪(并记录)连接的状态。一般conntrack用来指代“Connection Tracking”,即连接跟踪,是建立在 Netfilter框架之上的重要功能之一。 2、为什么需要链路跟踪 因…

天润融通「微藤大语言模型平台2.0」以知识驱动企业高速增长

8月23日,天润融通(又称“天润云”,2167.HK),正式发布「微藤大语言模型平台2.0」。 “大模型企业知识企业知识工程”。 “不能有效记录和管理知识的企业是不能持续进步的。在企业的生产流程中,相比于其他场景&#xff0…

Heikin Ashi最简单的一种烛台移动平均线

是不是每次进行交易的时候,市场上的各种新闻真真假假,搞的交易者每次都分不清楚,今天FPmarkets澳福给各位投资者推荐一种交易策略——“Heikin Ashi” “Heikin Ashi”只通过四个参数构建:开盘价、收盘价、最高价和最低价(最大和…

Vlan技术实操(第四课)

一 代码的常用命令一 vlan的增删改查 1)创建vlan[SW1]vlan 2 [2-4094] 创建vlan[SW1]vlan batch 10 20 30 创建多个不连续的vlan[SW1]display vlan 查看vlan信息[SW1]vlan batch 50 to 60创建多个连续的vlan[SW1]vlan2[SW1-vlan2]description caiwu添加描述信息&am…

分布式锁 总结

分布式锁 在应用开发中,特别是web工程开发,通常都是并发编程,不是多进程就是多线程。这种场景下极易出现线程并发性安全问题,此时不得不使用锁来解决问题。在多线程高并发场景下,为了保证资源的线程安全问题&#xff0…

震惊!友达台中厂长传过劳逝世 | 百能云芯

8月23日消息,近日面板大厂友达风波不断,8月3日有消息称,生产笔电的5代厂与电视的6代厂已经半年没有订单了,面板产业很惨,预计裁员100至200人。今天接到消息称,任职才1年的台中友达6A厂厂长,传因…

8月第3周榜单丨哔哩哔哩飞瓜数据B站UP主排行榜发布!

飞瓜轻数发布2023年8月14日-8月20日飞瓜数据UP主排行榜(B站平台),通过充电数、涨粉数、成长指数、带货数据等维度来体现UP主账号成长的情况,为用户提供B站号综合价值的数据参考,根据UP主成长情况用户能够快速找到运营能…

拨慢人体衰老时钟,MIT 利用 Chemprop 模型发现兼具药效与安全性的细胞抗衰化合物

内容一览:从光鲜亮丽的明星,到素装淡裹的普通人,大家都会无可避免地老去,经历形容的变化与身体机能的退化。正因为此,人们也在努力寻找延缓衰老的秘方。然而,现有的抗衰老药物总伴有一些副作用。近期&#…

大语言模型初学者指南 (2023)

大语言模型 (LLM) 是深度学习的一个子集,它正在彻底改变自然语言处理领域。它们是功能强大的通用语言模型,可以针对大量数据进行预训练,然后针对特定任务进行微调。这使得LLM能够拥有大量的一般数据。如果一个人想将LLM用于特定目的&#xff…

vue3 父子传值的使用

父传子: setup语法糖的写法: 子传父: setup语糖的写法:

STP知识点总结

目录 一.什么是STP协议 二.STP生成树协议产生的原因 三. STP生成树协议涉及的算法 一.802.1D 二.PVST 三.PVST 四. 快速生成树 五.MSTP 一.什么是STP协议 在一个二层交换网络中,生成一棵树型结构,逻辑的阻塞部分接口,使得从根到所有的…

代码记录鸭1

要实现登录有两个重要组成,一个是共享组件的应用程序项,另一个是共享组件的验证方案,先创建应用程序项: 名称有要求 改成新的ApexLogonTestWxx 创建成功 我设置的是启用 确定生成的用于导航到应用程序中其他页的 URL 是否应更易于…

如何评价国内的低代码开发平台(apaas)?

什么是低代码?低代码平台有什么价值?低代码开发到底能适应多广泛场景?低代码到底能做出多么复杂的应用?低代码平台应该如何筛选? 在低代码重新火爆的今天,我们又该如何利用低代码? 01 什么是a…

为何汽车品牌如此钟爱数字人?揭秘一种很新的「交互」营销思路

随着新能源补贴退坡,互联网行业高速发展的红利衰退,汽车行业竞争越来越激烈。 在数智化潮流冲击下,传统车企和新势力汽车品牌都纷纷借助数字人营销,打破增长困境,致力于推动数字人在车端以及营销内容的广泛应用&#…

生信豆芽菜-桑基图

网址:http://www.sxdyc.com/visualsPlotSankey 1、数据准备 表型信息: 2、设置图片的高度和宽度,提交等待运行成功 3、结果 当然,如果不清楚数据是什么样的,可以选择下载我们的示例数据,也可以关注&…

环肽52661-98-0;(3S)-3-(Hydroxymethyl)-2,5-piperazinedione

中文名:环(甘氨酰-L-丝氨酰) 环(甘氨酰-丝氨酰) 英文名:cyclo(Gly-Ser) cyclo(-gly-ser) 2,5-Piperazinedione, 3-(hydroxymethyl)-, (3S)- (3S)-3-(Hydroxymethyl)-2,5-piperazinedione CAS:52661-98-0 分子式&#xff1a…

锐捷ACL的基础知识--尚文网络敏姐

ACL控制访问列表 目录 ACL控制访问列表 1.1.ACL概念 1.2.ACL两大功能 1.ACL流量控制 2.ACL路由匹配 1.3.通配符 1.4. ACE访问控制表项 ACE概念 ACE两种动作 2.1.访问控制列表常用类型 IP标准ACL IP扩展ACL 2.2.访问控制列表的命名 数字命名 自定义名称 2.3.实验…

智慧工地:安防监控EasyCVR智慧工地视频监管风险预警平台的应用

智慧工地方案是一种结合现代化技术与工地管理实践的创新型解决方案。它通过实时监控、数据分析、人工智能等技术手段,使工地管理更加高效、智能化。在建设智慧工地的过程中,除了上述提到的利用物联网技术实现设备互联、数据采集及分析以外,还…

map函数用法

定义: map() 方法创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成 map()不会对空数组进行检测map()不会改变原始数组 语法 :map(function( element,index,array ){ }, thisArg) 参数说明: …