Kapı ödülü kazanma şansım nedir?


12

Yerel ACM bölümüm toplantılara gelen insanlara kapı ödülleri veriyor. Eğer programlama bulmacayı çözmek eğer (ama bununla birlikte, kazanan artmış şans ben hep bulmacayı çözmek). Bu nedenle, bazı kişiler 1, diğerleri 2 girişe sahiptir. Ama bekleyin! Çekiliş programının çalışması, birisi bulmacayı çözdüğünde başka bir giriş eklemek değildir. Bunun yerine, bir kişinin sahip olduğu "yaşam" sayısını izler ve bu kişi rastgele örnekleme algoritmasının her geçişinde seçilirse, azalır. Yani şu şekilde çalışır:

Doorknob: 1.  xnor: 2.  Justin: 2.  Alex: 1.  Dennis: 2.

Sonra program rastgele birini seçer [Doorknob, xnor, Justin, Alex, Dennis], sayıyı azaltır (seçtiğini söyle Justin):

Doorknob: 1.  xnor: 2.  Justin: 1.  Alex: 1. Dennis: 2.

Ve tekrarlar. Birinin "can" sayısı ( tekrar 0seçelim Justin) giderse , listeden kaldırılır:

Doorknob: 1.  xnor: 2.  Alex: 1.  Dennis: 2.

Bu bir kişi kalana kadar devam eder; o kişi kazanır.

Şimdi asıl soru şu ki, kazanma ihtimalim neydi?


Size iki giriş verilecektir:

  • n. Bu meydan okumaya giren kişi sayısı
  • k. Bu, n2 hayatı olanların sayısıdır . Bu numara her zaman sizi içerir.

Ben bir işlevi vardı Yani eğer pve denilen p(10, 5)5 (siz de dahil) 2 hayat var oysa ki, sadece 1 ömrüne sahip 5 tanesi 10 kişilik toplam vardır ödül kazanma olasılığı olurdu.


Kazanma olasılığını tam olarak veya ondalık olarak vermeniz beklenir. Her halükarda, cevaplar 4 dahil doğru adede kadar ve olmalıdır inci ondalık noktasından sonra ondalık haneye. Bu rakama yuvarlanıp dönmediğiniz size kalmış.

Çözümün 4 cevabını verir randomize çözüm olabilir inci ile bir ondalık basamağa yüksek olasılık . Kullandığınız yerleşik RNG'nin gerçekten rastgele olduğunu varsayabilirsiniz ve en az% 90 olasılıkla doğru cevabı vermelidir.

Ayrıca, n, k <= 1000merak edenler için daha büyük test senaryoları sağlamış olsam da, kodunuzun sadece çalışması gerekir .


Test Durumları

Not: Bunlardan bazıları genel formüllerdir.

n,    k   |  output
----------+---------
1,    1   |  1
2,    2   |  0.5
2,    1   |  0.75
3,    1   |  11/18 = 0.611111111
1000, 1   |  0.007485470860550352
4,    3   |  0.3052662037037037
k,    k   |  1/k
n,    1   |  (EulerGamma + PolyGamma[1 + n])/n    (* Mathematica code *)
          |  (γ + ψ(1 + n))/n
10,   6   |  0.14424629234373537
300,  100 |  0.007871966408910648
500,  200 |  0.004218184180294532
1000, 500 |  0.0018008560286627948
---------------------------------- Extra (not needed to be a valid answer)
5000, 601 |  0.0009518052922680399
5000, 901 |  0.0007632938197806958

Başka birkaç kontrol için p(n, 1) * naşağıdakileri yapın:

n     |  output
------+---------
1     | 1
2     | 1.5 
3     | 1.8333333333333335
10    | 2.928968253968254
100   | 5.1873775176396215
-------------------------- Extra (not needed to be a valid answer)
100000| 12.090146129863305

Artık bu sitedeki etiketlere aşina değilim; daha uygun bir etiket düşünüyorsanız, lütfen düzenleyin!
Justin

Math.se hakkında yakından ilgili soru: math.stackexchange.com/q/1669715/72616
Justin

Böylece, P (n, k) = ((k-1) / n) P (n, k-1) + ((nk) / n) P (n-1, k) + (1 / n) Q ( n, k-1), burada Q (n, k) = ((nk-1) / n) Q (n-1, k) + (k / n) Q (n, k-1) ve Q (1 , 0) = 1 ...
Rahibe

@KennyLau Bunu yorumlamaya çalışmayacağım, ancak fonksiyonun biraz farklı bir tanımını kullandığı için math.se linkine dikkat etmeyeceğim ( k
Justin

2
Tabii ki kesin olmamakla birlikte, cevabın yüksek olasılıkla dördüncü ondalık basamağa doğru olduğu konusunda yeterli denemelerle rastgele bir simülasyon yapmak uygun mudur?
xnor

Yanıtlar:


2

MATL , 42 bayt

:<~QXJx`J`tf1Zry0*1b(-tzq]f1=vts3e8<]6L)Ym

Bu olasılıklı (Monte Carlo) bir yaklaşım kullanır. Deney, olasılığın tahmin edildiği çok sayıda kez gerçekleştirilir. Gerçekleşmelerin sayısı , sonucun en az% 90 olasılıkla dördüncü ondalığa kadar doğru olmasını sağlamak için seçilir . Ancak, bu çok uzun zaman ve çok fazla bellek gerektirir. Gerçekleşmeleri sayısı aşağıdaki linke 10 kat azaltılmıştır 6 makul bir zaman amout programı biter böylece; ve sadece ilk ondalık sayının en az% 90 olasılıkla doğru olduğu garanti edilir.

EDIT (29 Temmuz 2016): dilde yapılan değişiklikler nedeniyle 6Ldeğiştirilmeleri gerekiyor 3L. Aşağıdaki bağlantı bu değişikliği içermektedir.

Çevrimiçi deneyin!

Arka fon

Let s olasılık hesaplanmasını göstermektedirler. Meydan açıklanan deney bir sayı için aday olacak n kez. Her seferinde ya ödülü kazanırsınız (“ başarı ”) ya da kazanmazsınız . N , başarıların sayısı olsun . İstenen olasılık N ve n'den tahmin edilebilir . N ne kadar büyük olursa, tahmin o kadar doğru olur. Anahtar soru, istenen doğruluğa ulaşmak için n'nin nasıl seçileceği , yani hatanın en az% 90'ının 10 −4'ten az olmasını sağlamaktır .

Monte Carlo yöntemleri olabilir

  • Sabit boyut : n değeri önceden sabitlenir (ve sonra N rastgele olur);
  • Değişken boyut : n , simülasyon sonuçlarıyla anında belirlenir.

İkinci kategori arasında, yaygın olarak kullanılan bir yöntem N'yi (istenen sayıda başarı) düzeltmek ve bu sayıda başarı elde edilene kadar simüle etmeye devam etmektir . Böylece n rastgele olur. Ters binom örnekleme veya negatif binom Monte Monte olarak adlandırılan bu teknik, tahmin edenin doğruluğunun sınırlandırılabilmesi avantajına sahiptir. Bu nedenle burada kullanılacaktır.

Özellikle, negatif binomial Monte Carlo ile x = ( N = 1) / ( n = 1) p'nin tarafsız bir tahmincisidir ; ve x'in p'den belirli bir orandan daha fazla sapma olasılığı üst sınır olabilir. Denklem (1) 'e göre bu kağıdın (koşullar (2) karşılanmadan Ayrıca not) alarak , N = 2.75 · 10 8 olduğu ya da daha büyük olmasını sağlar p / x aralığı [1,0001, 0,9999] ile en az% 90 aittir olasılık. Özellikle bu, x'in istendiği gibi en az% 90 olasılıkla 4. ondalık basamağa kadar doğru olduğunu gösterir .

Kod açıklandı

Kod bir bayt kaydetmek için N = kullanır 3e8. Bu kadar çok simülasyon yapmanın uzun zaman alacağını unutmayın. Bağlantıdaki kod, daha makul bir sürede çalışan N = kullanır 300(ilk test örnekleri için çevrimiçi derleyicide 1 dakikadan az); ancak bu sadece ilk ondalık sayının en az% 90 olasılıkla doğru olmasını sağlar.

:        % Take k implicitly. Range [1 ... k]
<~       % Take n implicitly. Determine if each element in the previous array is
         % less than or equal than n
Q        % Add 1. This gives an array [2 ... 2 1 ... 1]
XJx      % Copy to clipboard J. Delete from stack
`        % Do...while. Each iteration is a Monte Carlo realization, until the 
         % desired nunber of successes is reached
  J      %   Push previously computed array [2 ... 2 1 ... 1]
  `      %   Do...while. Each iteration picks one door and decrements it, until
         %   there is only one
    t    %     Duplicate
    f    %     Indices of non-zero elements of array
    1Zr  %     Choose one of them randomly with uniform distribution
    y0*  %     Copy of array with all values set to 0
    1b(  %     Assign 1 to chosen index
    -    %     Subtract
    tzq  %     Duplicate. Number of nonzero elements minus 1. This is falsy if
         %     there was only one nonzero value; in this case the loop is exited
  ]      %   End do...while
  f1=    %   Index of chosen door. True if it was 1 (success), 0 otherwise
  v      %   Concatenate vertically to results from previous realizations
  ts3e8< %   Duplicate. Is the sum less than 3e8? If so, the loop is exited
]        % End do...while
6L)      % Remove last value (which is always 1)
Ym       % Compute mean. This gives (N-1)/(n-1). Implicitly display

Haha,% 90'ının bunu zorlaştıracağının farkında değildim :-)
Justin

Evet, % 90 güven ile dördüncü ondalık gerçekten güçlü bir gereksinim :-)
Luis Mendo

2

Pyth, 34 bayt

Mc|!*HJ-GHch*J+*tHgGtH*gtGHKh-GHKG

Test odası

N , k'yi bağımsız değişken olarak galan deterministik bir memoized özyinelemeli işlevi tanımlar . yaklaşık 18 saniye içinde döner (çevrimiçi yorumlayıcıyı zaman aşımına uğradığı için yukarıdaki test paketine dahil değildir).g 1000 5000.0018008560286627952

Yaklaşık bir Python 3 çevirisi

@memoized
def g(n,k):
    return (not k*(n-k) or (1+(n-k)*((k-1)*g(n,k-1)+g(n-1,k)*(n-k+1)))/(n-k+1))/n

1

JavaScript (ES6), 65 bayt

f=(n,k,d=n-k)=>(!d||(f(n-1,k)*++d*--d+1+(--k&&f(n,k)*k*d))/++d)/n

Yine de büyük sayılarla denemeyin; f (30, 10) bile dikkate değer bir zaman alır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.