Ймовірності нокауту


9

Нокаут - це баскетбольна гра, в якій гравці по черзі стріляють. Він грається як послідовність змагань для двох гравців, кожен з яких має можливість "вибити" одного з цих гравців.

Припустимо, гравці A B C Dта їх шанси вистрілити та зробити кошик 0.1 0.2 0.3 0.4відповідно, незалежно від іншого гравця у змаганні. Два гравці в передній частині лінії, Aі B, "битися". Оскільки Aйде першим, він є захисником , загрожує усуненням і Bє нападником , а не загрожує негайним усуненням. Aпагони спочатку. Якщо Aвстигає, Aуспішно захистився і переходить до тилу рядка. Лінія зміниться на B C D A. Якщо Aне вдається, то Bстріляє. Якщо Bце встигає, то Aвиходить і Bпереходить до задньої частини рядка, тому лінія стає C D B. Якщо ніAі не Bробить це, процес повторюється, Aзнов стріляючи, поки Aабо не Bзробить кошик.

Припустимо, рядок змінено на B C D A( Aуспішно захищено). Тепер Bі C"воюйте", Bбудучи захисником і Cбути нападником. Цей процес повторюється, поки не залишиться лише одна людина. Ця людина є переможцем.

Ваше завдання - обчислити ймовірність перемоги кожної людини з урахуванням шансу, що вона зробить кошик.

Вхід :

Список номерів, таких як 0.1 0.2або 0.5 0.5 0.5 0.5, де n- го числа є шансом, що n- й гравець зробить кошик. Ви можете взяти цей вхід у будь-якому форматі, який вам подобається, в тому числі як параметри функції.

Вихід :

Список номерів, де n- е число - це шанс, що n- й гравець виграє гру. Ваші цифри повинні бути точними щонайменше до двох знаків після коми, щонайменше, 90% часу. Це означає, що ви можете використовувати підхід на основі моделювання. Однак, якщо ваш код не заснований на симуляції ( гарантовано повернути правильну відповідь принаймні на 6 десяткових знаків), тоді забирайте 30% від вашої оцінки.

Приклад між 0.5 0.5: Зателефонуйте гравцям Aта B. Нехай pбуде ймовірність виграшу. Aє 2/3шанс успішного захисту (оскільки є 1/2шанс Aзабити гол, 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/5або 0.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

Інтернет демо . Це рекурсивна функція, яка займає масив подвійних і повертає масив парних. Демонстрація в Інтернеті включає невелику кількість лісів для виконання функції та форматування виводу для відображення.

Розсічення

Основний принцип полягає в тому, що якщо n > 1залишилися гравці, один з них повинен бути наступним, хто буде вибитий. Більше того, порядок черги після цього відбувається залежить лише від початкового порядку черги та від того, хто вибивається. Таким чином, ми можемо робити nрекурсивні дзвінки, обчислювати ймовірність виграшу для кожного гравця в кожному конкретному випадку, а потім нам просто необхідно зважити і додавати.

Я позначу вхідні ймовірності як [p_0 p_1 ... p_{n-1}]. Нехай f(a,b)позначають ймовірність, від якої aне вдасться захиститися b. У будь-якому даному раунді є ймовірність aуспішного захисту p_a, ймовірність того, що bвибиває a, є (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); ймовірність того, що другого гравця нокаутують, є (1-f(0,1)) * f(1,2); третій гравець (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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.