博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
VBA实现两种方法生成任意概率分布的随机数
阅读量:6323 次
发布时间:2019-06-22

本文共 2831 字,大约阅读时间需要 9 分钟。

引子

一把武器的品质有分为最下级、下级、中级、上级、最上级五档,我希望在击杀一只怪物的时候,这把武器的掉率:最下级>下级>中级>上级>最上级,问如何设计满足上面的需求?
在游戏设计的过程中,经常会碰到需要设计很多不同的概率分布来达到一个系统的设计目的,让玩家在体验这个系统的时候感受更好,所以这时候均匀分布随机就不够用了,就需要开始为游戏设计不同的概率分布随机数。这里,介绍两种方法用来生成任意概率分布的随机数:逆变换方法、舍取方法。这两种算法其原理已被证实,所以这里不再进行论证,如果需要去探究其原理,可以去中国知网上搜索相关论文进行查看。
逆变换方法(Inverse Transform Method,ITM)
最简单的生成算法是Inverse Transform Method(下文简称ITM)。如果我们可以给出概率分布的累积分布函数(下文简称CDF)及其逆函数的解析表达式,则可以非常简单便捷的生成指定分布随机数。

  • ITM算法思路

  1. 根据给出的概率密度函数f(X)(PDF)积分得到其累积分布函数F(X)(CDF)
  2. 生成一个服从均匀分布的随机数S~U(0,1)
  3. 根据累积分布函数Y=F(X),求得其反函数X=F-1(Y)
  4. 返回X=F-1(S)作为本次生成的随机数

这种算法在实现时必须保证给出的概率密度函数,能够求出其累积分布函数CDF的逆函数,否则将无法求得所需要的随机数。下面就以指数分布为例,实现生成符合指数分布的随机数。

  • ITM方法的VBA实现

这里,先给出指数分布的PDF和CDF,λ是分布的一个参数,常被称为率参数(rate parameter)且λ>0。

概率密度函数

VBA实现两种方法生成任意概率分布的随机数 - 建筑学概论 - Seven的部落格

累积分布函数

VBA实现两种方法生成任意概率分布的随机数 - 建筑学概论 - Seven的部落格
1 Option Explicit 2 Option Base 1 3  4 Sub expDistribution() 5 Range("J:J").ClearContents 6 Range("J1") = "指数分布随机数" 7  8 Dim src As Single 'src:用来生成均匀分布随机数U(0,1) 9 Dim λ As Single 'λ:指数分布的参数10 Dim num As Integer 'num:生成的随机数个数11 Dim arr() As Integer 'arr():用来保存生成的随机数结果12 13 λ = Range("C10").value14 num = Range("C11").value15 16 ReDim arr(1 To num) As Integer17 Dim i As Integer18 For i = 1 To num Step 119 src = Rnd()20 arr(i) = WorksheetFunction.RoundDown(-1 / λ * Log(src), 0)21 Next22 23 For i = 1 To num Step 124 Range("J" & i + 1) = arr(i)25 Next26 End Sub
View Code
  • ITM实现结果

上述代码中可以看到,我将自己设定的30000个随机数(参数λ=0.3)都打印在表中J列单元格,这里给出最后的统计数据,如下。

VBA实现两种方法生成任意概率分布的随机数 - 建筑学概论 - Seven的部落格
VBA实现两种方法生成任意概率分布的随机数 - 建筑学概论 - Seven的部落格

可以看到,最终生成的30000个随机数,其数值的个数分布是符合之前给定的指数分布的。这种算法较为简洁高效,在能够使用的情况下,可以考虑优先使用该算法。

舍取方法(Acceptance-Rejection Method,ARM)
当无法给出CDF逆函数的解析表达式时,Acceptance-Rejection Method(下文简称ARM)是另外的选择。ARM的适用范围比ITM要大,只要给出概率密度函数(下文简称PDF)的解析表达式即可,而大多数常用分布的PDF是可以查到的。

  • ARM算法思路

    1. 设定我们需要实现的概率密度分布函数PDF为f(x),确定f(x)的定义域[xmin,xmax]、值域[ymin,ymax]
    2. 生成一个均匀分布随机数X~U(xmin,xmax)
    3. 生成一个均匀分布随机数Y~U(ymin,ymax)
    4. 如果Y≤f(X),则返回X作为本次的随机数;否则回到第2步

下面,依旧以指数分布为例,利用ARM实现该分布的随机数生成。

  • ARM方法的VBA实现

1 Option Explicit 2 Option Base 1 3  4   5  6 Sub ARMexpDistribution() 7 Range("J:J").ClearContents 8 Range("J1") = "指数分布随机数" 9 10 Dim src As Single 'src:用来生成第一个均匀分布随机数src~U(0,1 / λ * Log(λ / 0.0001))11 Dim dst As Single 'dst:用来生成第二个均匀分布随机数dst~U(0,λ)12 Dim λ As Single 'λ:指数分布的参数13 Dim num As Integer 'num:生成的随机数个数14 Dim arr() As Integer 'arr():用来保存生成的随机数结果15 16 λ = Range("C11").value17 num = Range("C12").value18 19 ReDim arr(1 To num) As Integer20 Dim i As Integer21 For i = 1 To num Step 122 Do23 src = Rnd() * 1 / λ * Log(λ / 0.0001)24 dst = Rnd() * λ25 Loop While dst > λ * Exp(-λ * src)26 arr(i) = WorksheetFunction.RoundDown(src, 0)27 Next28 29 For i = 1 To num Step 130 Range("J" & i + 1) = arr(i)31 Next32 End Sub
View Code
  • ARM实现结果

同样是生成30000个随机数,同样是参数λ=0.3,可以看到下面的列表中的统计数据以及统计图和第一种方法的实现结果是想吻合的,验证了这个方法的可行性。ARM本质上是一种模拟方法,而非直接数学方法。它每次生成新的随机数后,通过另一个随机数来保证其被接受概率服从指定的PDF。显然ARM从效率上不如ITM,但是其适应性更广,在无法得到CDF的逆函数时,ARM是不错的选择。

VBA实现两种方法生成任意概率分布的随机数 - 建筑学概论 - Seven的部落格
VBA实现两种方法生成任意概率分布的随机数 - 建筑学概论 - Seven的部落格
如果一种概率分布是由很多常见的概率分布组合而成,那么可以先生成常见概率分布的随机数,然后进行组合得到最终的概率分布随机数。

转载于:https://www.cnblogs.com/architecture101-gbt/p/8303378.html

你可能感兴趣的文章
C++11带来的优雅语法
查看>>
poj 2356 Find a multiple(鸽巢原理)
查看>>
第25本:《超级快速阅读》
查看>>
Unity中2D和UGUI图集的理解与使用
查看>>
ASP.NET MVC流程解说
查看>>
Cocos2D-X2.2.3学习笔记12(瞬间动作)
查看>>
LPC43XX JTAG Scan Chain
查看>>
web盲区(DNS,http)网站术语分析
查看>>
ZIP 算法详解 (转!)
查看>>
日月如梭,玩转JavaScript日期
查看>>
Android:BLE智能硬件开发详解
查看>>
C#语法造成的小问题(编译原理知识)
查看>>
oc 协议
查看>>
PowerShell 自动化管理 AWS (1) - 初始化连接
查看>>
什么是微服务
查看>>
CNN 那么多的网络有什么区别吗?看这里了解 CNN 的发展历程
查看>>
多云中如何共享责任模式
查看>>
Adenium约旦57MW太阳能光伏项目投产
查看>>
《Servlet和JSP学习指南》一3.6 动作
查看>>
物联网市场FD-SOI制程会取代FinFET吗?
查看>>