Peluang KO

9

Knockout adalah permainan bola basket tempat para pemain menembak secara bergantian. Ini dimainkan sebagai urutan dari kontes dua pemain, yang masing-masing memiliki kemungkinan "menjatuhkan" salah satu dari pemain tersebut.

Misalkan para pemain A B C Ddan peluang mereka menembak dan membuat keranjang 0.1 0.2 0.3 0.4masing - masing, terlepas dari pemain lain dalam kontes. Dua pemain di garis depan, Adan B, "berkelahi." Sejak Aberjalan lebih dulu, dia adalah bek , dalam bahaya disingkirkan, dan Badalah penyerang , dan tidak dalam bahaya eliminasi langsung. Atunas dulu. Jika Aberhasil, Atelah berhasil dipertahankan, dan pergi ke garis belakang. Garis akan berubah menjadi B C D A. Jika Atidak berhasil, maka Btunas. Jika Bberhasil, maka Akeluar dan Bpergi ke belakang garis, sehingga garis menjadi C D B. Jika tidakAatau Bmembuatnya, proses berulang, dengan Amenembak lagi, sampai salah satu Aatau Bmembuat keranjang.

Misalkan garis diubah menjadi B C D A( Atelah berhasil dipertahankan). Sekarang, Bdan C"berkelahi," dengan Bmenjadi pembela, dan Cmenjadi penyerang. Proses ini berulang sampai hanya satu orang yang tersisa. Orang itu adalah pemenangnya.

Tugas Anda adalah menghitung probabilitas setiap orang yang menang mengingat kemungkinan mereka akan membuat keranjang.

Masukan :

Daftar angka, seperti 0.1 0.2atau 0.5 0.5 0.5 0.5, di mana angka ke- n adalah kesempatan bahwa pemain ke- n akan membuat keranjang. Anda dapat mengambil input ini dalam format apa pun yang Anda suka, termasuk sebagai parameter untuk suatu fungsi.

Keluaran :

Daftar angka, di mana angka ke- n adalah kesempatan bahwa pemain ke- n akan memenangkan pertandingan. Angka Anda harus akurat ke setidaknya dua tempat desimal setidaknya 90% dari waktu. Ini berarti bahwa Anda dapat menggunakan pendekatan berbasis simulasi. Namun, jika kode Anda tidak berdasarkan simulasi ( dijamin untuk mengembalikan jawaban yang benar ke setidaknya 6 tempat desimal) maka ambil 30% dari skor Anda.

Contoh antara 0.5 0.5: Panggil para pemain Adan B. Membiarkan pmenjadi probabilitas menang. Amemiliki 2/3peluang untuk berhasil bertahan (karena ada 1/2peluang yang Amencetak gol, 1/4peluang yang Ameleset dan Bskor, dan 1/4peluang yang gagal dan proses berulang). Jika Agagal bertahan, dia tersingkir dan Bmenang. Jika Abertahan, maka garis itu menjadi B A. Karena situasinya simetris, probabilitas untuk Amenang adalah (1 - p). Kita mendapatkan:

p = 2/3 * (1 - p) + 1/3 * 0. Memecahkan, kita dapatkan p = 2/5. Outputnya harus 2/5 3/5atau 0.4 0.6.

Saya tidak cukup baik dengan probabilitas untuk melakukan contoh yang lebih kompleks.

Jika Anda membutuhkan lebih banyak kasus uji, berikut adalah beberapa:

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)
soktinpk
sumber

Jawaban:

4

CJam ( 84 80 karakter * 0,7 = 56)

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

Demo online . Ini adalah fungsi rekursif yang mengambil array ganda dan mengembalikan array ganda. Demo online mencakup sejumlah kecil perancah untuk menjalankan fungsi dan memformat output untuk ditampilkan.

Pembedahan

Prinsip dasarnya adalah jika ada n > 1pemain yang tersisa, salah satu dari mereka harus menjadi pemain berikutnya yang tersingkir. Selain itu, urutan antrian setelah itu terjadi hanya bergantung pada urutan awal antrian dan pada siapa yang tersingkir. Jadi kita bisa membuat npanggilan rekursif, menghitung probabilitas menang untuk setiap pemain dalam setiap kasus, dan kemudian kita hanya perlu mempertimbangkan dengan tepat dan menambahkan.

Saya akan memberi label kemungkinan input sebagai [p_0 p_1 ... p_{n-1}]. Biarkan f(a,b)menunjukkan probabilitas yang agagal bertahan b. Dalam setiap putaran tertentu, probabilitas yang aberhasil bertahan adalah p_a, probabilitas yang bkalah aadalah (1-p_a)*p_b, dan probabilitas untuk melanjutkan ke putaran lain adalah (1-p_a)*(1-p_b). Kita dapat melakukan penjumlahan eksplisit dari perkembangan geometris atau kita dapat berargumen bahwa dua perkembangan geometrik sebanding satu sama lain dengan alasan itu f(a,b) = (1-p_a)*p_b / (p_a + (1-p_a)*p_b).

Kemudian kita bisa naik satu level ke putaran penuh garis. Probabilitas bahwa pemain pertama tersingkir adalah f(0,1); probabilitas bahwa pemain kedua tersingkir adalah (1-f(0,1)) * f(1,2); pemain ketiga adalah (1-f(0,1)) * (1-f(1,2)) * f(2,3); dll sampai yang terakhir tersingkir dengan probabilitas \prod_i (1-f(i,i+1)) * f(n-1,0). Argumen yang sama tentang perkembangan geometris memungkinkan kita untuk menggunakan probabilitas ini sebagai bobot, dengan normalisasi oleh faktor 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
Peter Taylor
sumber