Qual è la possibilità che vincerò un premio per la porta?


12

Il mio capitolo ACM locale consegna premi alle persone che partecipano alle riunioni. Tuttavia, avrai maggiori possibilità di vincere se risolvi il puzzle di programmazione (ma io risolvo sempre quel puzzle). Quindi, alcune persone hanno 1 voce, mentre altre ne hanno 2. Ma aspetta! Il modo in cui funziona il programma della lotteria non è aggiungendo un'altra voce quando qualcuno risolve il puzzle. Invece, tiene traccia del numero di "vite" che una persona ha, diminuendo che se quella persona viene scelta in ogni passaggio del suo algoritmo di campionamento casuale. Quindi funziona così:

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

Quindi il programma sceglie casualmente uno dei [Doorknob, xnor, Justin, Alex, Dennis], diminuisce il numero (diciamo che sceglie Justin):

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

E si ripete. Se il numero di "vite" di qualcuno va a 0(scegliamo di Justinnuovo), vengono rimossi dall'elenco:

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

Questo continua fino a quando rimane una persona; quella persona è il vincitore.

Ora la vera domanda è: qual è stata la probabilità che avrei vinto?


Ti verranno dati due input:

  • n. Questo è il numero di persone iscritte alla sfida
  • k. Questo è il numero di persone (di quelle n) che hanno 2 vite. Questo numero include sempre te.

Quindi, se avessi una funzione pe chiamassi p(10, 5), sarebbe la probabilità di vincere il premio dove ci sono 10 persone in totale, 5 delle quali hanno solo 1 punto vita, mentre 5 (incluso te) hanno 2 punti vita.


Ci si aspetta che produca la probabilità di vincere esattamente o come un decimale. Ad ogni modo, le risposte devono essere accurate fino al 4 ° decimale incluso dopo il punto decimale. Che tu debba arrotondare a quella cifra dipende da te.

La tua soluzione può essere una soluzione randomizzata che genera la risposta al 4 ° decimale con alta probabilità . Si può presumere che l'RNG incorporato che si utilizza sia veramente casuale e che debba generare la risposta corretta con almeno il 90% di probabilità.

Inoltre, il tuo codice deve funzionare solo per n, k <= 1000, anche se ho fornito casi di test più grandi di quello per i curiosi.


Casi test

Nota: alcune di queste sono formule generali.

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

Per altri controlli, prendere p(n, 1) * ncome segue:

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

Non ho più familiarità con i tag su questo sito; se pensi a un tag più appropriato, modifica via!
Giustino,

Domanda strettamente correlata su math.se: math.stackexchange.com/q/1669715/72616
Giustino

Quindi, P (n, k) = ((k-1) / n) P (n, k-1) + ((nk) / n) P (n-1, k) + (1 / n) Q ( n, k-1), dove Q (n, k) = ((nk-1) / n) Q (n-1, k) + (k / n) Q (n, k-1) e Q (1 , 0) = 1 ...
Leaky Nun,

@KennyLau Non tenterò di interpretarlo, ma fai attenzione al link math.se, poiché utilizza una definizione leggermente diversa della funzione (credo ksia disattivata da uno)
Justin,

2
Va bene fare una simulazione randomizzata con prove sufficienti che la risposta sia corretta al quarto decimale con alta probabilità, anche se ovviamente non è una certezza?
xnor

Risposte:


2

MATL , 42 byte

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

Questo utilizza un approccio probabilistico (Monte Carlo). L'esperimento viene eseguito un gran numero di volte, da cui viene stimata la probabilità. Il numero di realizzazioni è selezionato per garantire che il risultato sia corretto fino al quarto decimale con probabilità almeno del 90%. Tuttavia, ciò richiede molto tempo e molta memoria. Nel link seguente il numero di realizzazioni è stato ridotto di un fattore di 10 6 in modo che il programma termini in un ragionevole lasso di tempo; e solo il primo decimale è garantito per essere accurato con almeno il 90% di probabilità.

EDIT (29 luglio 2016): a causa di cambiamenti nella lingua, 6Ldeve essere sostituito da 3L. Il link seguente incorpora quella modifica.

Provalo online!

sfondo

Sia p denotare la probabilità da calcolare. L'esperimento descritto nella sfida verrà eseguito per un numero n di volte. Ogni volta, o vinci il premio (" successo ") o no. Sia N il numero di successi. La probabilità desiderata può essere stimata da N e n . Più grande è n , più accurata sarà la stima. La domanda chiave è come selezionare n per soddisfare l'accuratezza desiderata, ovvero per assicurare che almeno il 90% delle volte l'errore sia inferiore a 10 −4 .

I metodi Monte Carlo possono essere

  • Dimensione fissa : un valore di n è fissato in anticipo (e quindi N è casuale);
  • Dimensione variabile : n è determinato al volo dai risultati della simulazione.

Tra la seconda categoria, un metodo comunemente usato è quello di correggere N (numero desiderato di successi) e continuare a simulare fino a raggiungere quel numero di successi . Quindi n è casuale. Questa tecnica, chiamata campionamento binomiale inverso o Monte Carlo binomiale negativo , ha il vantaggio di limitare l'accuratezza dello stimatore. Per questo motivo verrà utilizzato qui.

In particolare, con Monte Carlo negativo-binomiale x = ( N −1) / ( n −1) è uno stimatore imparziale di p ; e la probabilità che x si discosti da p di più di un dato rapporto può essere limitata. Secondo l'equazione (1) in questo documento (si noti anche che le condizioni (2) sono soddisfatte), prendendo N = 2.75 · 10 8 o superiore assicura che p / x appartiene all'intervallo [1.0001, 0.9999] con almeno il 90% probabilità. In particolare, ciò implica che x è corretto fino al 4 ° decimale con almeno il 90% di probabilità, come desiderato.

Codice spiegato

Il codice utilizza N = 3e8per salvare un byte. Notare che eseguire molte simulazioni richiederebbe molto tempo. Il codice nel collegamento utilizza N = 300, che viene eseguito in un periodo di tempo più ragionevole (meno di 1 minuto nel compilatore online per i primi casi di test); ma questo assicura solo che il primo decimale sia corretto con probabilità almeno del 90%.

:        % 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

Ahah non mi rendevo conto che il 90% lo avrebbe reso così difficile :-)
Justin

Sì, il quarto decimale con il 90% di confidenza è un requisito molto forte :-)
Luis Mendo,

2

Pyth, 34 byte

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

Suite di test

Definisce una funzione ricorsiva memorizzata deterministica gprendendo n , k come argomenti. g 1000 500ritorna 0.0018008560286627952in circa 18 secondi (non incluso nella suite di test sopra perché scade l'interprete online).

Una traduzione approssimativa di Python 3 sarebbe

@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 byte

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

Non provarlo con i grandi numeri però; anche f (30, 10) richiede un notevole lasso di tempo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.