在工作中計算經濟數值的時候,經常會遇到需要計算各種事件完成期望的工作(比如計算集齊一套特定的卡牌搭配需要抽多少次……)。本文就介紹一種比較快捷的計算方法。

一般來說,計算期望有以下幾種方法:

依據期望的定義式,套用某些概型公式,數學推導計算期望。

這種方法需要解題靈感,有了靈感五分鐘就解出來,沒思路的話就要卡很久。工作中不是很推薦這種方法,因為工作需要穩定的產出。

用vba寫程序模擬事件過程,跑很多次模擬期望次數。

這種穩定是達到了,但就是很麻煩,而且有的事件自己用vba寫出來的難度幾乎相當於重構了一遍項目對應模塊的代碼。

寫出該事件的狀態轉移矩陣,再用VBA處理求出具體期望。

以下介紹這種方法。


什麼是狀態轉移矩陣

就是一個矩陣,裡面的元素都是非負的,且各行元素之和為1.

舉個例子:
某個裝備有+0,+1,+2三種狀態。
+0強化至+1,成功率50%,失敗後等級不變。
+1強化至+2,成功率40%,失敗後等級下降至+0。
求由+0強化至+2的次數的期望值。

則該事件的一步狀態轉移矩陣可以寫為:

該事件的一步狀態轉移矩陣

第一列第一行的0.5代表,強化一次從狀態+0變為狀態+2的概率為0.5,
同理,第i列第j行的元素即代表強化一次從狀態i變為狀態j的概率。
一步狀態概率矩陣我們可以依照給定的情況很方便的寫出來。

什麼是K步狀態轉移矩陣

k步狀態轉移矩陣即為一步狀態轉移矩陣的K次方

矩陣的乘法規則自己百度。

舉個例子:
該事件的則該事件的二步狀態轉移矩陣可以經計算得到:

該事件的二步狀態轉移矩陣

第i列第j行的元素即代表強化二次從狀態i變為狀態j的概率。
可以看到,強化二次從狀態+0變為狀態+2的概率為0.2

同理我們可以獲得強化K次從狀態+0變為狀態+2的概率。

由期望定義式可知:

E(X)=sum_{k=1}^{infty}{XkPk}

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

輸出結果為:

即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


推薦閱讀:
相关文章