小弟對於遊戲裡的數值公式計算一直很有興趣,
剛好最近板上有不少人 PvP 關心攻擊屬性該如何取捨的問題,
在此分享一下我個人的研究心得。
本文將採用拉格朗日乘數 (Lagrange Multiplier) 的數學方法,
分析在不同配額 (即可分配的攻擊屬性點數) 下
攻擊力、暴擊率及暴擊機率的最佳分配比例,
並輔以 Python 程式驗證之。
另外,本文會解釋「邊際成長率」(Marginal Growth Rate) 的概念,
(即「為什麼大佬們常常說攻擊力稀釋效應很嚴重?」)
並示範如何藉此分析在已有屬性下最佳的屬性選擇。
因為使用的方法牽涉到微積分的基本概念,
為了讓更多人可以瞭解數學公式背後的意義,
我會盡量用簡單的文字說明,(「盡量」)
對數學推導沒有興趣的巴友則可以直接下拉到懶人包跟結論,
對於高品質聖遺物數量較多且套裝完整的玩家,
本篇心得分享可能不那麼有用;(警語)
畢竟對於畢業級的主 C 而言,
最佳的點數分配方法就是:
1. 優勢屬性傷害加成優先出
2. 想辦法出到攻擊力 212.1%、暴擊率 70.7%、暴擊傷害 141.4%
3. 剩下的多餘點數平均分配
相對於簡單直觀的主 C,
副 C、輔助要先考慮元素充能效率、元素精通等等;
如何在配額已經被限縮的情況下,
還能盡量提高自身的傷害效益,
反而會是本文比較著重的面向。
開始前容我再最後碎碎念一句:
玩遊戲是要讓自己開心的,
如果你高興,
想出 100% 暴擊率、50% 暴擊傷害也可以,
沒有必要因為這樣就彼此惡言相向。
但如果你覺得出裝還可以更好,
想追求更高的傷害效益,
希望本篇文章可以成為一點幫助。
本米只是一條鹹魚,對遊戲理解尚淺,
數學推導、遊戲環境考慮不周的地方,
歡迎各方好手批評指教。
懶人包
(這已經是我想得到在不失真的條件下最清楚的表達方式了,
如果還是太難,敬請見諒。我盡力了_(:3」∠)_)
最簡單 (但不精確的) 版本:
優勢屬傷有就出。
攻擊力先出到超過基礎值的兩倍,(綠字略大於白字。)
但請盡量不要超過三倍。(綠字超過白字的兩倍。)
如果有辦法暴擊率跟暴擊傷害超過 (40%, 80%) 才依 1 : 2 的比例疊雙暴,
不然全出攻擊力。
(實際雙暴比例不用這麼嚴格,1 : 3 到 3 : 4 都是可接受範圍。)
優勢屬性傷害加成優先出,
但是對元素輸出而言不建議超過 250% - (1/元素傷害占總傷害的比例)。
對物理輸出而言不建議超過 312.5% - (1/物理傷害占總傷害的比例)。
舉例而言,對純元素傷害輸出而言不建議超過 250%,
對 6 比 4 的元素、物理混傷輸出而言不建議超過 312.5% - 1/0.6 = 145.8%。
剩下三項數值 (攻擊力、暴擊率、暴擊傷害) 的最佳分配方法,有以下兩種方法判斷。
設總攻擊力百分比 ((白字 + 綠字)/白字) 為 x
總暴擊率為 y
總暴擊傷害為 z
並令配額函數 g(x, y, z) = x/3 + y/2 + z/4 = c
(計算的時候不需要計較加成的來源是什麼、基礎值是多少。角色面板寫多少就是多少。
如果白字、綠字分別是 600 跟 800,那麼你的 x 就是 (600 + 800)/600 = 2.33... ≒ 233.3%。)
一、 以邊際成長法計算最後一件聖遺物應該補充什麼屬性
在核心武器、聖遺物已經決定好了的情況下,
計算以下三項數值:
Gx = 3 / x (出攻擊力的邊際成長率)
Gy = 2 z / (1 + y z) (出暴擊率的邊際成長率)
Gz = 4 y / (1 + y z) (出暴擊傷害的邊際成長率)
哪個高就出哪個屬性。
例如 x = 200%,y = 30%、z = 100%,最後一件理之冠可選擇攻擊力、暴擊率或暴擊傷害
計算得:
Gx = 3 / 2.0 ≒ 1.5
Gy = 2 × 1.0 / (1 + 0.3 × 1.0) ≒ 1.538
Gz = 4 × 0.3 / (1 + 0.3 × 1.0) ≒ 0.923
最後一件選擇暴率頭最佳。
※此法不適用於連續的屬性選擇 (亦即有兩或三種以上的武器、聖遺物屬性加成可供選擇);
如需做多次選擇,請參考第二項。
二、以拉格朗日乘數計算各配額下的最佳調配
1. 若無法在 y > 51.6%、z > 103.3% 的情況下達到 x > 222.7%
假設暴擊率小於暴擊傷害的一半
(1) 在 x 達到 1.5 × (1/z + y) 之前一律疊高攻擊力。
(2) 前項達標後,按 3 : 2 的比例疊高攻擊力及暴擊率。
若暴擊傷害未達暴擊率的兩倍
(1) 在 x 達到 0.75 × (1/y + z) 之前一律疊高攻擊力。
(2) 前項達標後,按 3 : 4 的比例疊高攻擊力及暴擊傷害。
當 y 與 z 的比例接近 1 : 2,按 1 : 2 的比例疊高暴擊率及暴擊傷害並接上第 2 點。
2. 若第 1 點的條件可以滿足
(1) 在 y 達到 70.7% (或 z 達到 141.4%) 之前,
按 1 : 2 的比例疊高暴擊率及暴擊傷害到 70.7%、141.4%;
此階段可以犧牲部分攻擊力換取暴擊屬性 (但仍不應小於 212.1%)。
(2) 若 (x, y, z) 達到 (212.1%, 70.7%, 141.4%),
則平均分配三項屬性 (雙暴一樣是 1 : 2) 到 (225%, 100%, 200%)。
3. 若 y 達到 100% 還有剩餘配額,按 3 : 4 的比例繼續疊攻擊力及暴擊傷害。(雖然應該不可能...)
(最佳化的三項數值對於配額的函數圖。)
配額 c | 攻擊力 x | 暴擊率 y | 暴擊傷害 z | 傷害期望值 f |
1.0 | 255% | 5% | 50% | 2.6138 |
1.175 | 307.5% | 5% | 50% | 3.1519 |
1.25864- | 320.0% | 13.4% | 50% | 3.4143 |
1.25864+ | 222.7% | 51.6% | 103.2% | 3.4143 |
1.41421 | 212.1% | 70.7% | 141.4% | 4.2426 |
1.75 | 225% | 100% | 200% | 6.75 |
2.0 | 262.5% | 100% | 250% | 9.1875 |
如果你按照上述的建議去搭配,
最後有兩或三套以上的出裝 (指武器加聖遺物組合) 可以選擇,
那麼接著計算輸出分數:
DS = 面板攻擊力 × (1 + 暴擊率 × 暴擊傷害) × (1 + 屬性傷害加成 + 普攻傷害加成 + ...)
哪一套高就選哪一套。
前言
遊戲裡的傷害類型有很多種,普通攻擊、物理傷害、元素戰技、元素反應...
各種傷害類型都有各自的傷害計算公式,
然而除了超載、感電、超導跟擴散反應外,
其餘所有的傷害類型都會受到攻擊力、暴擊率以及暴擊傷害的加成。
(就連鍋巴、奧茲都會暴擊)
也因此如何將這三項數值做最有效的分配,
就成了傷害能否最佳化的重要議題。
對於這些傷害類型,可以寫出一般化的傷害公式:
傷害期望值 = [基礎攻擊力 × (1 + 百分比攻擊力) + 固定攻擊力]
× (1 + 暴擊率×暴擊傷害) × 傷害倍率
× (1 + 元素精通加成 + 反應傷害增強)
× (1 + 有的沒有的屬性傷害加成、普攻傷害加成、技能增傷...)
若將基礎攻擊力跟傷害倍率提出來,用數學式表達為:
f(x, y, z, EM, RA, wi) = x (1 + y z) (1 + EM + RA) (1 + w1 + w2 + ...)
其中 x 為總攻擊力百分比 ((白字 + 綠字)/白字)
y 為總暴擊率
z 為總暴擊傷害
EM、RA 分別為元素精通加成與反應傷害增強
wi 為各種屬性傷害加成
若再簡化只取攻擊力、暴擊率以及暴擊傷害的項,我們定義傷害期望值函數 f:
f(x, y, z) = x (1 + y z)
這就是我們希望最大化的數值。
然而角色能夠分配到攻擊屬性的配額有限,
也沒有辦法完美控制聖遺物副詞條的數值,
故我們應該考慮在「限制條件」下最大化傷害函數的方法。
聖遺物主屬性所提供的攻擊力、暴擊率、暴擊傷害數值
是 3 : 2 : 4 (同樣的星數、強化等級下),
副詞條雖然變數較大,但也大致上依循這個比例。
假如你選了 45% 的攻擊頭、就會犧牲 30% 的暴擊率;
你得到了 20% 的暴擊傷害,就要失去 15% 的攻擊力。
這就是邁向更高的傷害期望值時需要做的取捨。
我們可以定義配額函數 g:
g(x, y, z) = x/3 + y/2 + z/4 = c
在相同的聖遺物品質、數量之下,
你所能運用的配額 c 就是大致相等的。
另外,總攻擊力百分比不會低於 100% (即攻擊力不會低於基礎攻擊力),
暴擊率不會低於 5%,暴擊傷害不會低於 50%,
(如果你核心裝備有相關屬性的話下限值就會更高。)
是參數組 (x, y, z) 的先決條件。
對於最佳化問題,微分為零求極值是最常見的方法,
而在限制條件下的版本就是拉格朗日乘數。
本文接下來就會從邊際收益的概念出發
解釋拉格朗日乘數的核心精神,
並以此計算出在各種限制條件之下傷害期望值的最佳解。
還有一種稱為 Karush-Kuhn-Tucker 條件的方法,
專門處理等式、不等式限制條件混和的最佳化問題,
但是此法通常沒有解析解,
而且往往難以從結果瞭解它的數學意義,
所以本文會用它的一般版拉格朗日乘數,
搭配額外加入的不等式條件來作解析。
研究方法
首先我們來談談何謂「邊際收益」(Marginal Revenue)。
在經濟學的領域中,
邊際收益代表著在既定的生產組合之下,
每多生產 (銷售) 一單位的產品,所能得到的收益量。
當生產的產品越來越多,
所能收穫的利益就會越來越少,
同時所要付出的成本也會越來越高,
稱為「邊際收益遞減」與「邊際成本遞增」。
當邊際成本開始超過邊際收益,
繼續生產 (銷售) 產品的淨利反而會減少,
這時候的總銷售利潤就是最大值。
套到傷害計算公式上面來說,
每多分配 1 單位配額到某個屬性上,
(如:3% 的攻擊力、2% 的暴擊率、4% 的暴擊傷害或任意組合)
傷害期望值函數一樣會有對應的提升,
就是傷害期望值的邊際收益。
我們將 f(x, y, z) 對參數組 (x, y, z) 做全微分,可得:
df = (∂f/∂x) dx + (∂f/∂y) dy + (∂f/∂z) dz = fx dx + fy dy + fz dz
且因 1 點配額可以換得 3 點的攻擊力,或 2 點的暴擊率,或 4 點的暴擊傷害,
故我們可以得到疊三種屬性的邊際收益為:
Mx = df/dc (y, z 不變) = 3 fx = 3 (1 + y z) (出攻擊力的邊際收益)
My = df/dc (x, z 不變) = 2 fy = 2 x z (出暴擊率的邊際收益)
Mz = df/dc (x, y 不變) = 4 fz = 4 x y (出暴擊傷害的邊際收益)
舉例試算,假設 x = 200%、y = 5%、z = 50%:
Mx = 3 × (1 + 0.05 × 0.5) = 3.075
My = 2 × 2.0 × 0.5 = 2.0
Mz = 4 × 2.0 × 0.05 = 0.4
而當攻擊力來到 300%,其他兩項不變:
Mx = 3 × (1 + 0.05 × 0.5) = 3.075
My = 2 × 3.0 × 0.5 = 3.0
Mz = 4 × 3.0 × 0.05 = 0.6
我們可以看到,當我們只疊攻擊力,邊際收益並不會因此下降,
但是出其他屬性的邊際收益會漸漸超過出攻擊力的邊際收益,
此時出其他屬性的效益就會比只出攻擊力還要好。
至於大佬們常說的「攻擊力稀釋」又是怎麼回事?
如果我們把邊際收益除以傷害期望值函數,我們可以得到邊際成長率 (Marginal Growth Rate):
Gx = 3 / x (出攻擊力的邊際成長率)
Gy = 2 z / (1 + y z) (出暴擊率的邊際成長率)
Gz = 4 y / (1 + y z) (出暴擊傷害的邊際成長率)
這個數字代表著每多分配一點配額,
傷害期望值會成長為原本的多少比例。
當 x = 200%,Gx = 1.5;
當 x = 300%,Gx = 1.0。
從這裡我們就可以看出,在單一數值較低的時候,
同樣的點數可以帶來較大的比例成長,
但越往上疊,成長率就越低,
這個時候出其他數值的成長效果就會越好,
這就是「屬性稀釋效應」。
照著同樣的邏輯,不只是攻擊力,
任何屬性的成長率都會隨著該屬性的單調增加而減少;
(包括屬性傷害加成、普攻傷害加成、增傷效果...)
這也是為什麼大佬們都會建議你平均分配屬性的原因。
從這裡我們也可以看出為什麼建議暴擊率跟暴擊傷害要是 1 : 2。
如果參數組 (x, y, z) 是一個最佳組合,
那麼我們應該要得到 Gx = Gy = Gz。
(否則就會有出其中一種屬性優於另外兩種的狀況,
代表還沒有達成最佳解。)
解 2 z / (1 + y z) = 4 y / (1 + y z)
得 z = 2 y
用白話文說就是,
雖然 y = z 是 y z 的最佳解,
但是 y 比 z 貴一倍,
所以 z = 2 y 才是在該問題限制條件下的最佳解。
在實務上,只要根據你當下的參數,
計算出各屬性的邊際成長率 G,
就可以找出當下最佳該出的屬性是什麼。
這就是懶人包裡提到的「邊際成長法」。
但是請注意,如果你有很多個武器效果、聖遺物可供選擇,
邊際成長法並不能保證連續選擇下的結果會是最佳的結果;
(也就是說,每一次根據邊際成長率來做的最佳選擇合在一起並不一定是最佳的。)
如果要處理這種情況,就要參考接下來要介紹的拉格朗日乘數。
拉格朗日乘數 (Lagrange Multiplier) 告訴我們,
如果我想知道目標函數 f(x) 的最大值,
但是參數組 x 必須滿足某種限制條件 g(x) = 0,
(g(x) = c 的形式也可以,令 h(x) = g(x) - c = 0 就好,
不影響結果,以下不再贅述。)
那麼我可以創造一個新的拉格朗日函數 L:
L(x, λ) = f(x) - λ g(x)
這個新函數的極大值問題就會包含原函數的極大值問題;
換句話說就是設 L 對參數組 x 跟 λ 微分為零求極值。
「微分為零求極值」是我們在學習微積分時一定會碰到的例題,
基本的精神就是「如果一個函數的值在某點附近不再增減,
那麼該函數在該點有極大值或極小值」。
(更嚴格來說,該點還必須不是「反曲點」。)
但是如果我的參數本身受到某種限制,該怎麼處理?
拉格朗日乘數的精神就是:
「如果一個函數在符合限制條件下的某一點附近不再增減,
那麼該函數在該點有極大值或極小值」。
假設獨立變數有三個 (x, y, z),
並有限制條件為 g(x, y, z) = 0,
這相當於我要求在 g(x, y, z) = 0 的條件下
df = (∂f/∂x) dx + (∂f/∂y) dy + (∂f/∂z) dz = 0
在 c 不變的條件下,
dg = (∂g/∂x) dx + (∂g/∂y) dy + (∂g/∂z) dz = dc = 0
顯然 fx : fy : fz = gx : gy : gz 是一個解,
( df = fx dx + fy dy + fz dz = λ gx dx + λ gy dy + λ gz dz
= λ (gx dx + gy dy + gz dz) = λ dc = 0 )
故我們得到:
(∂f/∂x) - λ (∂g/∂x) = 0
(∂f/∂y) - λ (∂g/∂y) = 0
(∂f/∂z) - λ (∂g/∂z) = 0
等價於:
∂L/∂x = (∂f/∂x) - λ (∂g/∂x) = 0
∂L/∂y = (∂f/∂y) - λ (∂g/∂y) = 0
∂L/∂z = (∂f/∂z) - λ (∂g/∂z) = 0
∂L/∂λ = g = 0
這就是拉格朗日乘數最簡單直觀的證明。
套用到我們關注的問題,
我們得到最佳化 (x, y, z) 的條件是
fx : fy : fz = 1/3 : 1/2 : 1/4
但這相當於
3 fx = 2 fy = 4 fz
也就是
Mx = My = Mz 或是 Gx = Gy = Gz
這可以與邊際成長法中求最佳解的條件互相印證。
然而在我們關注的問題中,
還有 x ≧ 100%、5% ≦ y ≦ 100%、z ≧ 50% 的不等式條件存在,
除了微分為零的地方,目標函數的極大值也可能發生在邊界上,
拉格朗日乘數無法處理這樣的問題。
數學一點地說明,
如果今天目標函數是一個凸函數 (Convex Function) 或凹函數 (Concave Function),
上面的內部解就一定會是最大職或最小值,
但我們處理的傷害期望值函數不是,所以... _(:3」∠)_
所幸,邊界上的最大值問題一樣可以用拉格朗日乘數解決,
邊界有幾個就解幾次拉格朗日乘數,
最後再把所有發生極大值的地方放在一起比較,
得到所有極大值之中的最大值。
這並不是一個簡單的工程,
也有一些難以準確分析的區域,
但是借助程式的方法,
我們可以得到近乎準確的結論。
以下開始展示應用拉格朗日乘數的詳細分析。
數學分析與應用
我們想要求目標函數 f(x, y, z) 在限制條件 g(x, y, z) = c 下的最大值。
這個問題的拉格朗日函數為:
L(x, y, z, λ) = x (1 + y z) - λ (x/3 + y/2 + z/4 - c)
接下來我們微分求極值:
∂L/∂x = (1 + y z) - λ/3 = 0
∂L/∂y = x z - λ/2 = 0
∂L/∂z = x y - λ/4 = 0
∂L/∂λ = -(x/3 + y/2 + z/4 - c) = 0 (這條就是限制條件 g(x, y, z) = 0,最後再處理它。)
經過消去法,我們可以得到 f(x, y, z) 達到極值時的條件:
x = 3 (1/y + 2 y) / 4
y = y
z = 2 y
套回 g(x, y, z) = c 可得:
y = c/3 ± √(4 c^2 - 6)/6
(x, z 用 y 的結果帶入)
可以得到在 √1.5 ≦ c < 1.75 及 √1.5 ≦ c < 1.375 兩個區間
分別有兩個內部解 (x, y, z)。
從這個結果來看,
不管你原本攻擊力、暴擊率或暴擊傷害是多少,加成效果來自哪裡,
只要你最後的暴擊率跟暴擊傷害是 1 比 2,
且百分比攻擊力跟暴擊率的關係如上所述,
你的傷害就會是極大化。
另外,由配額函數 g 計算出的配額 c 也一樣,
其絕對的數值在實務上並不重要,
只有當你想比較同角色拿不同武器,
或是不同角色之間最佳化屬性分配的差異時,
才需要特別去詳細計算。
然而這個推導有兩個缺陷;
其一為實際上我們無法隨心所欲調配各數值的比例,
其二為原問題的最大值可能發生在參數組的邊界上。
(另外,聖遺物副詞條數值加成的比例也未必總是 3 : 2 : 4。)
如果我們觀察 y = c/3 ± √(4 c^2 - 6)/6 這個內部解,
會發現 y 在 c < √1.5 ≒ 1.22474 時無解,
意味著此時最佳解必定落在邊界上。
這就是為什麼配額偏低 (裝備較差) 的時候堆攻擊力是最好的策略。
為了處理最大值在邊界上的情況,
我們可以對每個可能的邊界做一次拉格朗日乘數,
然後分析在各配額下最佳化的參數組應該符合什麼關係式。
我們先考慮 x ≧ 100%、5% ≦ y ≦ 100%、z ≧ 50% 的邊界,
這個時候需要比較的邊界解就多達 9 種。
(還要加上剛剛用拉格朗日乘數算出來的兩個內部解。)
不過不用擔心,本米已經幫大家整理好了,
以下使用 Python 語言 matplotlib 模組包下的 pyplot 函數繪圖呈現。
(內部解與各邊界解在各配額下的比較關係。)
我們可以將此函數圖劃分成三個區域:
1. (0.15 + 1/3) ≦ c < 1.175,粉色函數勝出,
為 y = 5%、z = 50%,只疊攻擊力的邊界解 (x, 0.05, 0.5)。
2. 1.175 ≦ c < 1.25864,綠色函數勝出,
為 z = 50%,按 3 : 2 的比例疊攻擊力與暴擊率的邊界解 (3(1 + 0.5y), y, 0.5)。
3. 1.25864 ≦ c < 1.75,黑色函數勝出,
為上述拉格朗日乘數得到的內部最佳解 (3(1/y + 2 y)/4, y, 2 y)。
4. c > 1.75,看起來像綠色的黃色函數勝出,
為暴擊率已達 100%,按 3 : 4 的比例疊攻擊力與暴擊傷害的邊界解 (3(1 + z)/4, 1.0, z)。
什麼?你說看不到黑色函數比綠色函數低?
我們再放大一點看。
(配額在 1.2 到 1.3 之間粉、綠、黑三個邊界解的比較關係。)
進一步,我們可以繪製出最佳化參數組 (x, y, z) 對配額的關係圖,
並在各區段分析最佳的屬性分配:
(最佳化的三項數值對於配額的函數圖。)
1. 在攻擊力達到 307.5% 之前,只疊攻擊力會是最佳解。
2. 續第 1 項,在 307.5% ≦ x < 320.0% 這個區間,應按 3 : 2 的比例疊高攻擊力及暴擊率。
3. 續第 2 項,當 (x, y, z) 超過 (320.0%, 13.4%, 50%),
最佳解會瞬間跳到從 (222.7%, 51.6%, 103.3%) 開始的內部解。
這個時候我們會想按 1 : 2 的比例疊高暴擊率及暴擊傷害。
但同時我們也觀察到在 (x, y, z) 到達 (212.1%, 70.7%, 141.4%) 之前,
最佳化的攻擊力是往下掉的,
意思是不必強求攻擊力,甚至可以犧牲部分攻擊力來換取雙暴屬性。
4. 當 (x, y, z) 超過 (212.1%, 70.7%, 141.4%),
最佳化的攻擊力會慢慢增加,
此時應保持暴擊率與暴擊傷害 1 : 2 繼續疊高,
並適度分配點數到攻擊力直到 (225%, 100%, 200%)。
5. 這個區段暴擊率已經到達 100%,無法再提升了,
接下來按 3 : 4 的比例疊高攻擊力與暴擊傷害會是最佳解。
(極品聖遺物加上角色突破加成有可能達到這個領域,但是不容易。)
因為區域 2 的寬度較窄,且此區域內的三個最佳邊界解差異不大,
實務上是可以無視的。
另外,在配額為 1.41421 時,純堆攻擊力跟按 1 : 2 疊雙暴有著約 9% 的差異,
配額越高差距只會越大,
所以在裝備有一定品質之後建議轉而疊雙暴。
為驗證本最佳化分析的可信度,
我們使用 Python 語言 Scipy 模組包下的 SLSQP 方法,
計算出各配額下的最佳解,並同樣做圖。
給有興趣的人:
import scipy.optimize as opt
def dmg_f(x):
return x[0]*(1 + x[1]*x[2])
def cons_f(x, c):
return x[0]/3 + x[1]/2 + x[2]/4 - c
def dmg_opt(c):
c = max(0.15 + 1/3, c)
obsf = lambda x: -dmg_f(x)
init = [1.0, 0.05, 0.5]
cons = [{'type': 'eq', 'fun': lambda x: cons_f(x, c)}]
bound = [(1.0, None), (0.05, 1.0), (0.5, None)]
res = opt.minimize(obsf, x0 = init,\
bounds = bound,\
constraints = cons,\
tol = 1e-14)
dmg = -res.fun
para = res.x
lndmg = np.log(dmg)
return dmg, para, lndmg
(程式計算出的最大傷害期望值函數值與其對數值對配額作圖)
(程式計算出的最佳化的三項數值對配額作圖。)
我們可以看到趨勢是符合前述討論的,
然而區域 2 的寬度卻有明顯的不同。
從程式算出的最大傷害期望值函數圖可以發現
在 c = √1.5 ≒ 1.22474 的地方有一個小折點,
推測是程式基於不明原因提前走到區域 3 的內部解,
但實際上在 √1.5 ≦ c < 1.25864 內部解還沒有超越邊界解 (3 + 1.5 y, y, 0.5),
可以合理認為是程式所採用的 SLSQP 方法存在著某些缺陷。
scipy.optimize.minimize() 函數有個臭名是
你給定的起始點不同,你會得到不一樣的極值點,
所以會有一些小偏差實際上是不令人意外的。
如果要解決這個問題,就要想辦法給函數一點額外的限制,
不然就得自己寫一個 Python 函數來解最佳化問題_(:3」∠)_。
然而實務上我們很難完全沒有額外暴擊率、暴擊傷害,
很多時候都是已經有 (舉例) y0 = 32%、z0 = 84 % 的前提下去調配,
這個時候我們就必須求符合 y ≧ y0 及 z ≧ z0 的邊界解
還有在這範圍內可能的內部解。
其結果可以分成兩個部分:
1. 暴擊率小於暴擊傷害的一半
這個時候出暴擊率的效益是大於暴擊傷害的,
因此我們考慮攻擊力跟暴擊率要怎麼調配。
以拉格朗日乘數得邊界解為 (1.5(1/z + y), y, z0),
也就是按 3 : 2 的比例疊高攻擊力及暴擊率。
2. 若暴擊傷害未達暴擊率的兩倍
這個時候出暴擊傷害的效益是大於暴擊率的,
因此我們考慮攻擊力跟暴擊傷害要怎麼調配。
以拉格朗日乘數得邊界解為 (0.75(1/y + z), y0, z)。
也就是按 3 : 4 的比例疊高攻擊力及暴擊傷害。
這個結果相當於區域 2 的擴張 (或縮小)。
直觀的的論述是,
初始暴擊傷害越高,越支持提早出暴擊率;
初始暴擊率越高,越支持提早出暴擊傷害。
當 y 與 z 的比例接近 1 : 2,內部解會逐漸超過邊界解,
若 z0 > 81.6% (或 y0 > 40.8%),在 z = 2 y 的時候可以無縫接上內部解,
但是其他的情況就沒有一個明確的判斷式 (應該是沒有解析解)。
不過因為這個時候邊界解與內部解的傷害期望值函數值差距不太大,
所以只要先把 y 跟 z 調配到接近 1 : 2 之後,
按 1 : 2 的比例疊高暴擊率及暴擊傷害並接上內部解 (3(1/y + 2 y)/4, y, 2 y),
就可以得到 (接近) 最大化的傷害期望值。
如果需要準確的轉換區資訊,可以參考下表。
暴擊傷害 z | 轉換區配額 c | 轉換區參數 (x, y, z) | 轉換區傷害期望值 f |
50% | 1.175 ~ 1.25864 | (307.5%, 5%, 50%) ~ (320.0%, 13.4%, 50%) | 3.1519 ~ 3.4143 |
81.7% | 0.86641 ~ 1.22474 | (191.2%, 5%, 81.7%) ~ (244.9%, 40.8%, 81.7%) | 1.9898 ~ 3.2660 |
100% | 0.8 ~ 1.25 | (157.5%, 5%, 100%) ~ (225%, 50%, 100%) | 1.6538 ~ 3.375 |
141.4% | 0.75711 ~ 1.41421 | (113.6%, 5%, 141.4%) ~ (212.1%, 70.7%, 141.4%) | 1.2160 ~ 4.2426 |
200%* | 0.91667 ~ 1.75 | (100%, 16.7%, 200%) ~ (225.0%, 100%, 200%) | 1.3333 ~ 6.75 |
* 暴擊率達到 16.7% 前全出暴擊率。
暴擊率 y | 轉換區配額 c | 轉換區參數 (x, y, z) | 轉換區傷害期望值 f |
25%* | 1.25 | (300%, 25%, 50%) | 3.375 |
40.8% | 1.06641 ~ 1.22474 | (221.2%, 40.8%, 50%) ~ (244.9%, 40.8%, 81.7%) | 2.6633 ~ 3.2660 |
50% | 1.0 ~ 1.25 | (187.5%, 50%, 50%) ~ (225%, 50%, 100%) | 2.3438 ~ 3.375 |
70.7% | 0.95711 ~ 1.41421 | (143.6%, 70.7%, 50%) ~ (212.1%, 70.7%, 141.4%) | 1.9432 ~ 4.2426 |
100% | 1.0 ~ 1.75 | (112.5%, 100%, 50%) ~ (225.0%, 100%, 200%) | 1.6875 ~ 6.75 |
* 攻擊力達到 300% 前全出攻擊力,之後接上內部解。
剩下的內容就跟懶人包一樣了。
這個結果可以解釋為什麼有些角色應該按 1 : 2 疊暴擊率及暴擊傷害,
有些只需要疊攻擊力,有些則需要交互疊。
主 C 配額夠高,可以毫無懸念疊雙暴,
副 C、工具人如果暴擊傷害 (或暴擊率) 不夠高,就多疊攻擊力,
暴擊傷害 (或暴擊率) 夠高,就輪流出攻擊力跟暴擊率。
實際操作方面,
因為屬性加成可能受到武器屬性、效果、聖遺物屬性和詞條等各種來源影響,
不可能隨意調控相關參數的比例,
所以常常是搭好幾套裝備之後,
計算輸出分數來決定優劣。
輸出分數可以寫成:
DS = 面板攻擊力 × (1 + 暴擊率 × 暴擊傷害)
最後選擇輸出分數最高的那套裝備來使用。
舉例來說,第一套裝備給你 1800 點攻擊力、30% 暴擊率及 80% 暴擊傷害,
第二套裝備給你 1400 攻擊力、50% 暴擊率及 100% 暴擊傷害,
計算得第一套的輸出分數 = 1800 × (1 + 0.3 × 0.8) = 2232
第二套的輸出分數 = 1400 × (1 + 0.5 × 1.0) = 2100
第一套略勝,故選擇第一套。
需要特別注意的是這裡的輸出分數沒有考慮元素精通加成及反應傷害增強,
如果關注的是吃重元素反應的角色,
則上述的討論將無法直接適用。
另外,如果要考慮有特定屬性傷害加成的裝備,
請看接下來的討論。
(最大傷害期望值函數值對配額作圖。)
(最大傷害期望值函數值的邊際成長率與配額的關係圖)
上圖灰線是對數化的傷害期望值函數,
下圖灰線則為前述函數的微分,
令 F = ln f
則 F' = f' / f = G
該微分即為前述函數的邊際成長率。
我們可以看到當配額超過 0.817,
邊際成長率不會再超過 1.5,也不低於 1.1。
因此疊屬性傷害加成 (及普攻傷害加成、大招傷害加成) 的時候,
不建議疊到邊際成長率小於 1.1。
(之所以把屬性傷害加成分開討論,是因為只能從空之杯和套裝效果獲得,相對獨立。)
設優勢屬性傷害占所有傷害的比例為 p,
屬性傷害加成為 w,
則 G (屬性傷害加成) = 3 d ln(1 + p w) / dw = 3 p / (1 + p w) ≧ 1.2,
(3 的倍數是因為屬性傷害加成跟攻擊力一樣,每點配額可以換 3 點。)
得 w ≦ 2.5 - 1/p。
角色的優勢屬性是物理傷害時,
因為物理傷害加成的配額比重是 3.75,
故上述條件式變更為 3.75 p / (1 + p w) ≧ 1.2
得 w ≦ 3.125 - 1/p。
如果是純元素輸出 (普攻也是屬性傷害的法師角色) 大可把屬性傷害加成當成攻擊力疊。
如果是元素、物理混傷輸出,優勢屬性傷害的占比 (p 值) 越重,
越適合疊高屬性傷害加成,
但是除非你是全程後台掛元素工具人,
不然不適合像法師那樣堆疊屬性傷害加成。
個人是建議穿對應的屬性傷害加成套,
之後的空之杯用邊際成長法判斷應該出攻擊力還是屬性傷害加成 。
(或是反過來,先裝屬傷杯,再決定要穿什麼套裝。)
普攻傷害加成、大招傷害加成等等有的沒有的加成
與屬性傷害加成屬於同一個增幅項 (大部分人稱之為「乘區」),
其邊際成長率會受到彼此的數值稀釋影響,
故除非普攻 (或大招) 佔角色輸出手段的絕大部分,
否則不建議跟屬性傷害加成一起出。
最後,
弱勢屬性傷害加成提升的傷害量一定比不上優勢方,
(優勢屬性傷害加成越疊高會有越嚴重的稀釋效應,
但是弱勢傷害一樣會因總傷害提高而被稀釋。)
所以一般來說不必考慮弱勢方的屬性傷害加成;
除非戰術上你需要特定種類的元素傷害,
為了平衡屬性傷害比例才會去考慮。
結論
用拉格朗日乘數可以得到在配額夠高的情況下,1 : 2 疊雙暴是效益最高的選擇。
(此時只要總攻擊力 > 212.1%,不需要過度疊高攻擊力。)
若是配額不足,則按照暴擊傷害與暴擊率的高低比例,
決定如何交互疊高攻擊力與暴擊率 (或暴擊傷害)。
初始暴擊傷害越高,越適合提早出暴擊率;
初始暴擊率越高,越適合提早出暴擊傷害。
主 C 裝備成形後,疊雙暴效果最佳;
副 C、輔助若攻擊屬性配額較少或裝備較差,以出攻擊力為主。
(天賦有吃其他屬性加成的另當別論。)
屬性傷害加成 (及普攻傷害加成、大招傷害加成) 則根據你的角色類型及你慣用的輸出手段,
搭配其他攻擊屬性來出。
任何攻擊屬性都不應該單獨疊高 (屬性傷害加成也不例外),
需要時用邊際成長法來衡量什麼時候是出太多了,
或是做為套裝效果選擇的參考。
多套武器、聖遺物搭配在選擇時,
計算最後的輸出分數做比較,
分數越高的配裝效果越好。
謝謝大家的觀看。歡迎批評指教。