はじめに
とあるソシャゲをやっていると、確率で成功する強化アイテムがありました。その確率が、
- はじめは一定の確率 $p$
- 失敗するたびに 1% 増加
というものでした。実際の確率が表記通りかという問題は置いといて、確かにこれだと天井も分かりやすいし、なんなら天井までにあたりが来る確率がとても高そうでいい設定だなあと思いました。実際、遊んでいると50% を超えるまでたまったことがほとんどないです。
一方、期待値が自明でないと思いました。なので、ちょっと計算する式とプログラムを考えてみます。
問題設定
試行を行うと確率であたりまたははずれを引くイベントがある。 $k$ 回目の試行では $P(k) = p + (k - 1)\times \Delta p$の確率であたりを引く。ここで $\Delta p = (1 - p)/(N - 1)$ である。これは以下の要請を満たす。
- 外れるたびにあたりの確率が一定の量だけ増えていく。
- $k = N$ で $P(N) = 1$ となって必ずあたりを引く。
このとき、あたりを1回引くまで繰り返し試行を行ったとき、あたりを初めて引く回数の期待値を知りたい。
数式で
まず $k - 1$回目まではすべて失敗する確率は
$$
Q(k) = \prod_{i=1}^{k-1}\left(1 - P(i)\right)
$$
としますと、$E = \sum_{k=1}^N kQ(k)P(k)$ なので、
$$
\begin{eqnarray}
E & = & \sum_{k=1}^N k\left[\prod_{i=1}^{k-1}\left(1 - P(i)\right)\right]\left[p + (k-1)\Delta p\right] \\
& = & \sum_{k=1}^N k\left[\prod_{i=1}^{k-1}\left(1 - p - \frac{(i-1)(1-p)}{N-1}\right)\right]\left[p + \frac{(k-1)(1-p)}{N-1}\right]
\end{eqnarray}
$$
です。ちょっと考えてみましたが、良い感じの変形が思いつきませんでした。思いついたら追記します。
数値解で
上の式を愚直にコードに落とし込んだものになります。
import matplotlib.pyplot as plt
import numpy as np
def calc_E(p, N):
deltaP = (1 - p)/(N - 1)
E = 0.0
prob_allF = 1.0
for k in range(1, N + 1):
Pk = p + (k - 1)*deltaP
prob_firstT = prob_allF*Pk
E += k*prob_firstT
prob_allF *= (1 - Pk)
return E
実験
0% ~ 98% について、上昇幅 1% のときに何回くらい試行すればあたりを引けるかをグラフで描いてみます。
def main():
p = 0.01*np.arange(99)
deltap = 0.01
N = (1 - p)/deltap + 1
E_numerical = [calc_E(pi, int(Ni)) for pi, Ni in zip(p, N)]
plt.plot(p*100, E_numerical, label="Numerical")
plt.legend()
plt.show()
if __name__ == "__main__":
main()
これでこんな結果になりました。
50%以上はほぼ2回以下というのは直観にも合います。それほど間違ってはなさそうですね。
感覚として10% の時でも数十回はしないという感じだったのですが、実際7回程度で引けそうという結果でした。たとえ 0% はじまりでも15回程度もやればあたりを引けそうということで、思いのほか少ないと思いました。