引子
一把武器的品质有分为最下级、下级、中级、上级、最上级五档,我希望在击杀一只怪物的时候,这把武器的掉率:最下级>下级>中级>上级>最上级,问如何设计满足上面的需求?
在游戏设计的过程中,经常会碰到需要设计很多不同的概率分布来达到一个系统的设计目的,让玩家在体验这个系统的时候感受更好,所以这时候均匀分布随机就不够用了,就需要开始为游戏设计不同的概率分布随机数。这里,介绍两种方法用来生成任意概率分布的随机数:逆变换方法、舍取方法。这两种算法其原理已被证实,所以这里不再进行论证,如果需要去探究其原理,可以去中国知网上搜索相关论文进行查看。
逆变换方法(Inverse Transform Method,ITM)
最简单的生成算法是Inverse Transform Method(下文简称ITM)。如果我们可以给出概率分布的累积分布函数(下文简称CDF)及其逆函数的解析表达式,则可以非常简单便捷的生成指定分布随机数。
-
ITM算法思路
- 根据给出的概率密度函数f(X)(PDF)积分得到其累积分布函数F(X)(CDF)
- 生成一个服从均匀分布的随机数S~U(0,1)
- 根据累积分布函数Y=F(X),求得其反函数X=F-1(Y)
- 返回X=F-1(S)作为本次生成的随机数
这种算法在实现时必须保证给出的概率密度函数,能够求出其累积分布函数CDF的逆函数,否则将无法求得所需要的随机数。下面就以指数分布为例,实现生成符合指数分布的随机数。
-
ITM方法的VBA实现
这里,先给出指数分布的PDF和CDF,λ是分布的一个参数,常被称为率参数(rate parameter)且λ>0。
概率密度函数
累积分布函数
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").value 14 num = Range("C11").value 15 16 ReDim arr(1 To num) As Integer 17 Dim i As Integer 18 For i = 1 To num Step 1 19 src = Rnd() 20 arr(i) = WorksheetFunction.RoundDown(-1 / λ * Log(src), 0) 21 Next 22 23 For i = 1 To num Step 1 24 Range("J" & i + 1) = arr(i) 25 Next 26 End Sub