Qualcuno può dirmi come simulare , dove , usando un gettone (tutte le volte che vuoi) con ?
Stavo pensando di utilizzare il campionamento del rifiuto, ma non sono riuscito a inchiodarlo.
Qualcuno può dirmi come simulare , dove , usando un gettone (tutte le volte che vuoi) con ?
Stavo pensando di utilizzare il campionamento del rifiuto, ma non sono riuscito a inchiodarlo.
Risposte:
Poiché ci sono innumerevoli soluzioni, ne troviamo una efficiente .
L'idea alla base di questa inizia con un modo standard per implementare una variabile di Bernoulli: confrontare una variabile casuale uniforme con il parametro . Quando , restituisce ; altrimenti, restituisce .a / b U < a / b 1 0
Possiamo usare -coin come un generatore di numeri casuali uniforme . Per generare un numero uniformemente entro qualsiasi intervallo , lancia la moneta. Quando è head, genera in modo ricorsivo un valore uniforme nella prima parte dell'intervallo; quando sono code, genera ricorsivamente dall'ultima parte dell'intervallo. Ad un certo punto l'intervallo target diventerà così piccolo che non importa davvero come scegli un numero da esso: è così che inizia la ricorsione. È ovvio che questa procedura genera variate uniformi (fino a qualsiasi precisione desiderata), come è facilmente dimostrato dall'induzione.X p X 1 - p
Questa idea non è efficiente, ma porta a un metodo efficiente. Dato che in ogni fase traccerai un numero da un determinato intervallo , perché non controllare prima se è necessario disegnarlo? Se il tuo valore target non rientra in questo intervallo, conosci già il risultato del confronto tra il valore casuale e il target. Pertanto, questo algoritmo tende a terminare rapidamente. (Ciò potrebbe essere interpretato come la procedura di campionamento del rifiuto richiesta nella domanda.)
Possiamo ottimizzare ulteriormente questo algoritmo. In ogni fase, in realtà abbiamo due monete che possiamo usare: rietichettando la nostra moneta possiamo farne una che è testa con possibilità . Pertanto, come precomputazione, possiamo ricorsivamente scegliere quale rietichettatura porta al numero inferiore previsto di lanci necessari per la risoluzione. (Questo calcolo può essere un passaggio costoso.)
Ad esempio, è inefficiente utilizzare una moneta con per emulare direttamente una variabile di Bernoulli : in media occorrono quasi dieci lanci. Ma se usiamo una moneta , allora in soli due lanci saremo sicuramente fatti e il numero atteso di lanci è solo .( 0,01 ) p = 1 - 0,0 = 0,1 1,2
Ecco i dettagli
Partizionare qualsiasi intervallo semiaperto dato negli intervalli
Questo definisce le due trasformazioni e che operano a intervalli semiaperti.s ( ∗ , T )
Per motivi di terminologia, se un insieme di numeri reali, lascia che l'espressione
significa che è un limite inferiore per : per tutti . Analogamente, significa è un limite superiore per .
Scrivi . (In effetti, non farà alcuna differenza se è reale anziché razionale; richiediamo solo )
Ecco l'algoritmo per produrre una variabile con il parametro Bernoulli desiderato:
Impostare e .
While {Lancia la moneta per produrre . Impostare Incremento .}
Se imposta . Altrimenti, impostare . Z = 1 Z = 0
Per illustrare, ecco R
un'implementazione dell'aloritmo come funzione draw
. I suoi argomenti sono il valore target e l'intervallo , inizialmente . Utilizza la funzione ausiliaria implementando . Sebbene non sia necessario, traccia anche il numero di lanci di monete. Restituisce la variabile casuale, il conteggio dei lanci e l'ultimo intervallo ispezionato.[ x , y ) [ 0 , 1 ) ss
s <- function(x, ab, p) {
d <- diff(ab) * p
if (x == 1) c(ab[1], ab[1] + d) else c(ab[1] + d, ab[2])
}
draw <- function(target, p) {
between <- function(z, ab) prod(z - ab) <= 0
ab <- c(0,1)
n <- 0
while(between(target, ab)) {
n <- n+1; ab <- s(runif(1) < p, ab, p)
}
return(c(target > ab[2], n, ab))
}
Come esempio del suo uso e prova della sua precisione, prendi il caso e . Tracciamo valori usando l'algoritmo, riportiamo sulla media (e il suo errore standard) e indichiamo il numero medio di flip usati.p = 0,9 10 , 000
target <- 0.01
p <- 0.9
set.seed(17)
sim <- replicate(1e4, draw(target, p))
(m <- mean(sim[1, ])) # The mean
(m - target) / (sd(sim[1, ]) / sqrt(ncol(sim))) # A Z-score to compare to `target`
mean(sim[2, ]) # Average number of flips
In questa simulazione dei erano teste. Sebbene inferiore all'obiettivo di , il punteggio Z di non è significativo: questa deviazione può essere attribuita al caso. Il numero medio di salti mortali era poco --a meno di dieci. Se avessimo usato la moneta da , la media sarebbe stata di - non ancora significativamente diversa dall'obiettivo, ma in media sarebbero stati necessari solo lanci .0,01 - 0,5154 9,886 1 - p 0,0094 1.177
Ecco una soluzione (un po 'disordinata, ma è la mia prima pugnalata). Puoi effettivamente ignorare e WLOG assume . Perché? Esiste un algoritmo intelligente per generare un lancio di moneta imparziale da due lanci di monete distorti. Quindi possiamo assumere .
Per generare un , posso pensare a due soluzioni (la prima non è la mia, ma la seconda è una generalizzazione):
Lancia la moneta imparziale volte. Se testa non è presente, ricominciare. Se teste sono presenti, di ritorno se la prima moneta è un testa a testa o no (a causa )
Questo può essere esteso a qualsiasi valore di . Scrivi in forma binaria. Ad esempio,
Creeremo un nuovo numero binario usando i lanci di monete. Inizia con e aggiungi le cifre a seconda che appaia una testa (1) o una coda (0). Ad ogni lancio, confronta il tuo nuovo numero binario con la rappresentazione binaria di fino alla stessa cifra . Alla fine i due divergeranno e ritorneranno se è maggiore del tuo numero binario.
In Python:
def simulate(p):
binary_p = float_to_binary(p)
binary_string = '0.'
index = 3
while True:
binary_string += '0' if random.random() < 0.5 else '1'
if binary_string != binary_p[:index]:
return binary_string < binary_p[:index]
index += 1
Qualche prova:
np.mean([simulate(0.4) for i in range(10000)])
è circa 0.4 (non veloce comunque)
Vedo una soluzione semplice, ma senza dubbio ci sono molti modi per farlo, alcuni presumibilmente più semplici di così. Questo approccio può essere suddiviso in due passaggi:
Generando da due eventi con uguale probabilità data una procedura ingiusta di lancio della moneta (la combinazione della moneta particolare e il metodo con cui viene lanciata generando una testa con probabilità ). Possiamo chiamare questi due eventi ugualmente probabili e . [Esiste un approccio semplice per questo che richiede di eseguire coppie di lanci e per produrre due risultati ugualmente probabili, con tutti gli altri risultati che portano alla generazione di una nuova coppia di rotoli per riprovare.]H ∗ T ∗ H ∗ = ( H , T ) T ∗ = ( T , H )
Ora generi una camminata casuale con due stati assorbenti usando la moneta simulata corretta. Scegliendo la distanza degli stati assorbenti dall'origine (uno sopra e uno sotto di esso), è possibile impostare la possibilità di assorbimento dicendo che lo stato assorbente superiore è un rapporto desiderato di numeri interi. In particolare, se si posiziona la barriera di assorbimento superiore su e quella inferiore su (e si avvia il processo dall'origine) e si esegue la camminata casuale fino all'assorbimento, la probabilità di assorbimento sulla barriera superiore è .- ( b - a ) a
(Ci sono alcuni calcoli da fare qui per dimostrarlo, ma puoi ottenere le probabilità abbastanza facilmente lavorando con le relazioni di ricorrenza ... oppure puoi farlo sommando serie infinite ... o ci sono altri modi.)
[self-study]
tag e leggi la sua wiki . Nota che non è necessario presentare una richiesta di aiuto alla fine della tua domanda: sappiamo che tutti coloro che pubblicano qui sperano in aiuto!