e的矩阵次方_利用状态转移矩阵和VBA求游戏中各种事件达成次数的期望

在工作中计算经济数值的时候,经常会遇到需要计算各种事件完成期望的工作(比如计算集齐一套特定的卡牌搭配需要抽多少次……)。本文就介绍一种比较快捷的计算方法。

一般来说,计算期望有以下几种方法:

依据期望的定义式,套用某些概型公式,数学推导计算期望。

这种方法需要解题灵感,有了灵感五分钟就解出来,没思路的话就要卡很久。工作中不是很推荐这种方法,因为工作需要稳定的产出。

用vba写程序模拟事件过程,跑很多次模拟期望次数。

这种稳定是达到了,但就是很麻烦,而且有的事件自己用vba写出来的难度几乎相当于重构了一遍项目对应模块的代码。

写出该事件的状态转移矩阵,再用VBA处理求出具体期望。

以下介绍这种方法。


什么是状态转移矩阵

就是一个矩阵,里面的元素都是非负的,且各行元素之和为1.

举个例子:
某个装备有+0,+1,+2三种状态。
+0强化至+1,成功率50%,失败后等级不变。
+1强化至+2,成功率40%,失败后等级下降至+0。
求由+0强化至+2的次数的期望值。

则该事件的一步状态转移矩阵可以写为:

f9c4ee15ac080e540a84d58b55dba149.png
该事件的一步状态转移矩阵
第一列第一行的0.5代表,强化一次从状态+0变为状态+2的概率为0.5,
同理,第i列第j行的元素即代表强化一次从状态i变为状态j的概率。
一步状态概率矩阵我们可以依照给定的情况很方便的写出来。
什么是K步状态转移矩阵

k步状态转移矩阵即为一步状态转移矩阵的K次方

矩阵的乘法规则自己百度。

举个例子:
该事件的则该事件的二步状态转移矩阵可以经计算得到:

bf954145f04ee14a674aecd25338104d.png
该事件的二步状态转移矩阵
第i列第j行的元素即代表强化二次从状态i变为状态j的概率。
可以看到,强化二次从状态+0变为状态+2的概率为0.2

同理我们可以获得强化K次从状态+0变为状态+2的概率。

由期望定义式可知:

Xk=K

Pk=[K步状态转移矩阵中的Pij]-[K-1步状态转移矩阵中的Pij]

然后累加即可。

之所以Pk=[K步状态转移矩阵中的Pij]-[K-1步状态转移矩阵中的Pij],是因为[K步状态转移矩阵中的Pij]包含了[K-1步状态转移矩阵中的Pij],减去后才是仅经过K次强化后强化至+2的次数。
(其实就是一个概率分布函数)
Pij的值最终会收敛于1
用VBA计算上述过程,代码如下(我写的程序比较糙,属于能跑起来的那种):
Sub Matrix()
Dim i, j, k, a(1 To 10000, 1 To 10, 1 To 10), b(1 To 10000, 1 To 10, 1 To 10), p(1 To 1000), e(1 To 1000)

For i = 1 To 3              '一步转移矩阵写入
 For j = 1 To 3
    a(1, i, j) = Cells(i + 3, j + 2)
 Next j
Next i

p(1) = 0

For k = 2 To 1000            'K步转移矩阵计算
 For i = 1 To 3
  For j = 1 To 3

a(k, i, j) = a(1, i, 1) * a(k - 1, 1, j) + a(1, i, 2) * a(k - 1, 2, j) + a(1, i, 3) * a(k - 1, 3, j)

  Next j
 Next i
 p(k) = a(k, 1, 3)            'Pk=[K步状态转移矩阵中的Pij]
Next k

e(1) = 0

For k = 2 To 1000
 e(k) = e(k - 1) + k * (p(k) - p(k - 1))     '累加求和求得最终期望值
Next k

MsgBox e(1000)

End Sub

输出结果为:

a81bcc696d776ab34f67e570a982ec2f.png

即E(x)=7.5

我们用另一种方法验算一下。

设装备从等级k-1强化到等级k的期望是E(k),每次强化成功概率是p1,不变概率是p2,掉级概率是p3。
现在分析从k-1级强化到k级的过程的几种情况
情况一:一次成功,由于成功的概率是p1,强化到k级花费的次数是1,这种情况下需要次数的期望是1 * p1 = p1。
情况二:不变,等级不变又回到从k-1级强化到k级的过程,不变概率是p2,强化到k级花费的次数是1 + E(k)(1代表强化等级不变消耗的次数,E(k)是从k-1级到k级的期望),这种情况下需要次数的期望是(1 + E(k)) * p2。
情况三:掉1级,掉1级变成需要从k-2级强化到k-1级,再从k-1级强化到k级,掉级概率是p3,强化到k级花费的次数是1 + E(k - 1) + E(k)(1代表强化掉级,E(k - 1)是从k-2级到k-1级的期望,E(k)是从k-1级到k级的期望),这种情况下需要次数的期望是(1 + E(k - 1) + E(k)) * p3。
综合上述三种情况,
装备从等级k-1强化到等级k的期望E(k) = p1 + (1 + E(k)) * p2 + (1 + E(k - 1) + E(k)) * p3。
再加上初始条件E(0) = 0,就可以求出E(1)、E(2)....E(n),把E(1)、E(2)....E(n)加起来就是从0级到n级的期望了。

求得E(1)=2,E(2)=5.5

则E(x)=7.5

一致。


因为游戏中的过程状态都是离散的,所以这个方法基本可以处理所有的求期望相关的问题,只需要把一步状态转移矩阵写出来就行。

于是我们就可以处理各种骚问题了,比如打boss会有50%随机掉ABC中的任意一个装备,已知在已持有A的时候B的掉率会下降5%,但持有B的时候C的掉率上升5%,balabalabalabala,问集齐一套ABC期望打多少次boss。
这种问题用概型解或者用写程序跑都是及其痛苦的。但是我们可以快速的列出一步状态转移矩阵,用vba快速解出答案:
这种情况下,会有以下状态:都没、只有A、只有B、只有C、只有AB、只有AC、只有BC、都有,其一步状态转移矩阵是一个7*7的矩阵,你们可以试着写一下,然后用本文的算法算一下,很快就能求出从状态【都没】到状态【都有】的次数期望。

我发现了一种更简单的办法

mathematica中有内置的离散马科夫过程函数,可以进行快捷的计算:

第一步:列出一步状态转移矩阵

第二步:在Mathematica中读取一步状态转移矩阵

xlsxPath= "C:UsersAdministratorDesktop一步状态转移矩阵.xlsx";

m =Import[xlsxPath, "Data"][[1]][[2 ;; 4, 2 ;; 4]]
第二行从指定excel读取数据,2;;4表示2~4行,2;;4表示2~4列(这是直接读取xlsx文件的写法,若使用mathematica link for excel加载宏,可以使用Excel[“A1:C1”]这种更好理解的语法)

第三步:定义一个马尔科夫过程:

markovProcess = DiscreteMarkovProcess[1,m];

· DiscreteMarkovProcess(Mathematica内置的离散马科夫过程函数),接收2个参数:初始状态和状态转移矩阵

· 赋值这个离散马科夫过程到变量markovProcess

Mean[FirstPassageTimeDistribution[markovProcess,10]]

Mean用于计算分布的期望值

markovProcess = DiscreteMarkovProcess[1,m];
Mean[FirstPassageTimeDistribution[markovProcess,3]]

输出结果为7.5

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值