ノックアウト確率


9

ノックアウトは、プレーヤーが交代で撃つバスケットボールゲームです。それは、2人のプレーヤーのコンテストのシーケンスとして再生されます。各コンテストは、それらのプレーヤーの1人を「ノックアウト」する可能性があります。

プレーヤーがそうでA B C Dあり、射撃とバスケットを作るチャンスが0.1 0.2 0.3 0.4それぞれ、コンテストの他のプレーヤーとは無関係であると仮定します。最前線にいる2人の選手、AそしてB「ファイト」。以来A最初に行く、彼はディフェンダーに排除される危険で、そしてBある攻撃者の即時撤廃の危険にさらされていない、と。A最初に撃つ。成功した場合Aは、A防御に成功し、列の最後に移動します。行はに変わりB C D Aます。Aうまくいかない場合は、B発砲します。作成した場合BA外に出Bて行の後ろに移動するので、行はになりC D Bます。どちらでもない場合ABして、それ、プロセスの繰り返しを作るAのいずれかになるまで、再び撮影AまたはBバスケットになります。

行がB C D AA正常に防御された)に変化したとします。さて、BそしてC「ファイト」B、そしてディフェンダーでありC、アタッカーである。このプロセスは、一人だけが残るまで繰り返されます。その人が勝者です。

あなたの仕事は、バスケットを作るチャンスを与えられた勝者一人一人の確率を計算することです。

入力

数字などのリスト0.1 0.20.5 0.5 0.5 0.5N番目の数は可能性あるのn番目のプレイヤーがバスケットを行います。この入力は、関数へのパラメーターとしてを含め、任意の形式で取得できます。

出力

数字のリスト。n番目の数字は、n番目のプレーヤーがゲームに勝つ確率です。数値は、少なくとも90%の確率で小数点第2位まで正確でなければなりません。つまり、シミュレーションベースのアプローチを使用できます。ただし、コードがシミュレーションベースではない場合(少なくとも小数点以下6桁に正解が返されることが保証されている場合)、スコアから30%を取り除きます。

間の例0.5 0.5:プレーヤーAとを呼び出しBます。pAが勝つ確率を見てみましょう。防御に成功Aする2/3可能性があります(スコア1/2A獲得する1/4チャンス、AミスとBスコアを獲得する1/4チャンス、ミスとプロセスの両方が繰り返される可能性があるため)。A防御に失敗した場合、彼はノックアウトされてB勝利します。A防御する場合、ラインはになりB Aます。状況は対称的であるため、A勝つ確率はです(1 - p)。我々が得る:

p = 2/3 * (1 - p) + 1/3 * 0。解決、我々が得ますp = 2/5。出力は次のようになります2/5 3/50.4 0.6

より複雑な例を実行する確率は十分ではありません。

さらにテストケースが必要な場合は、次の例をご覧ください。

0.1 0.2 0.3 0.4 --> 0.01 0.12 0.25 0.62
0.99 0.99 --> 0.5 0.5 (it's not exact, but if you round to two decimal places, you get 0.5 and 0.5)

回答:


4

CJam(84 80文字* 0.7 = 56)

{_,({_,,{_2$m<(;(+Q0\)\++m>\}%)_(+.{X2$-*_@+/}1\{1$*\1$-}%)1\-f/.f*:.+}{,da}?}:Q

オンラインデモ。これは、doubleの配列を取り、doubleの配列を返す再帰関数です。オンラインデモには、関数を実行して出力を表示用にフォーマットするための小さな足場が含まれています。

解剖

基本的な原則は、n > 1プレイヤーが残っている場合、そのうちの1人が次にノックアウトされるプレイヤーでなければならないということです。さらに、その後のキューの順序は、キューの最初の順序と誰がノックアウトされるかにのみ依存します。そのため、n再帰呼び出しを行って、各プレーヤーの勝率を計算し、適切な重み付けと追加を行う必要があります。

入力確率をとラベル付けします[p_0 p_1 ... p_{n-1}]。に対する防御に失敗するf(a,b)確率を示しましょう。どのラウンドでも、防御に成功する確率は、ノックアウトする確率は、別のラウンドに進む確率はです。幾何学的進行の明示的な合計を行うか、2つの幾何学的進行が互いに比例していると主張することができます。abap_aba(1-p_a)*p_b(1-p_a)*(1-p_b)f(a,b) = (1-p_a)*p_b / (p_a + (1-p_a)*p_b)

次に、レベルをフルラウンドまで上げることができます。最初のプレーヤーがノックアウトされる確率は次のとおりですf(0,1)。2番目のプレーヤーがノックアウトされる確率は(1-f(0,1)) * f(1,2)、3番目のプレーヤーは(1-f(0,1)) * (1-f(1,2)) * f(2,3)です。等々、最後までノックアウトされる可能性があり\prod_i (1-f(i,i+1)) * f(n-1,0)ます。幾何学的な進行に関する同じ議論により、これらの確率を重みとして使用し、係数で正規化することができ1 / \prod_i f(i, i+1 mod n)ます。

{                   e# Define a recursive function Q
  _,({              e# If we have more than one person left in the line...
    _,,{            e#   Map each i from 0 to n-1...
      _2$m<         e#     Rotate a copy of the probabilities left i times to get [p_i p_{i+1} ... p_{n-1} p_0 ... p_{i-1}]
      (;(+          e#     i fails to defend, leaving the line as [p_{i+2} ... p_{n-1} p_0 ... p_{i-1} p_{i+1}]
      Q             e#     Recursive call
      0\)\++        e#     Insert 0 for the probability of i winning and fix up the order
      m>\           e#     Rotate right i times and push under the list of probabilities
    }%
    )               e#   Stack: [probs if 0 knocked out, probs if 1 knocked out, ...] [p_0 p_1 ...]
    _(+.{           e#   Duplicate probs, rotate 1, and pointwise map block which calculates f(a,b)
      X2$-*_@+/     e#     f(a,b) = (1-p_a)*p_b / (p_a + (1-p_a)*p_b)  TODO is the d necessary?
    }
    1\{1$*\1$-}%    e#   Lift over the list of f(a,b) a cumulative product to get the weights  TODO is the d necessary?
    )1\-f/          e#   Normalise the weights
    .f*             e#   Pointwise map a multiplication of the probabilities for each case with the corresponding weight
    :.+             e#   Add the weights across the cases
  }{,da}?           e# ...else only one left, so return [1.0]
}:Q
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.