Sì e no, a seconda di cosa intendi con "l'unico modo". Sì, in quanto non esiste un metodo che è garantito per terminare, il meglio che puoi fare (per i valori generici di e ) è un algoritmo che termina con probabilità 1. No, in quanto puoi rendere i "rifiuti" piccoli come desidera.RNR
Perché la risoluzione garantita è impossibile in generale
Supponiamo di avere un motore di calcolo deterministico (una macchina di Turing o qualunque cosa galleggi la tua barca), oltre a un oracolo che genera elementi casuali del set di elementi . Il tuo obiettivo è generare un elemento del set -element . L'output del tuo motore dipende solo dalla sequenza di valori restituiti dall'oracolo; è una funzione di quella sequenza potenzialmente infinita .[ 0 .. R - 1 ] N [ 0 , N - 1 ] f ( r 0 , r 1 , r 2 , ... )R[0..R−1]N[0,N−1]f( r0, r1, r2, ... )
Supponiamo che il tuo motore chiami l'oracolo al massimo volte. Potrebbero esserci tracce per le quali l'oracolo viene chiamato meno di volte; in tal caso, chiamare i tempi supplementari dell'oracolo in modo che sia sempre chiamato esattamente volte non modifica l'output. Quindi, senza perdita di generalità, assumiamo che l'oracolo sia chiamato esattamente volte. Quindi la probabilità del risultato è il numero di sequenze tale che . Poiché l'oracolo è un generatore casuale uniforme, ogni sequenza è equiprobabile e ha probabilità . Quindi la probabilità di ogni risultato è della formam m m x ( r 0 , … , r m - 1 ) f ( r 0 , … , r m - 1 ) = x 1 / R m A / R m A 0 R mmmmmX( r0, ... , rm - 1)f( r0, ... , rm - 1) = x1 / RmA / Rmdove è un numero intero compreso tra e .UN0Rm
Se divide per alcuni , puoi generare una distribuzione uniforme su elementi chiamando il generatore casuale volte (questo viene lasciato come esercizio al lettore). Altrimenti, questo è impossibile: non c'è modo per ottenere un risultato con probabilità . Nota che la condizione equivale a dire che tutti i fattori primi di sono anche fattori di (questo è più permissivo di quello che hai scritto nella tua domanda; ad esempio puoi scegliere un elemento casuale tra 4 con una fiera a 6 facce muori, anche se 4 non divide 6).R m m N m 1 / N N RNRmmNm1 / NNR
Ridurre gli sprechi
Nella tua strategia, quando , non devi ridisegnare immediatamente. Intuitivamente, c'è ancora un po 'di entropia in che puoi tenere nel mix.[ kr≥kN[kN..R−1]
Si supponga per un momento che si continui in realtà la generazione di numeri casuali sotto per sempre, e si genera di loro alla volta, rendendo disegna. Se un semplice campionamento del rifiuto su questa generazione raggruppata, lo spreco su è , ovvero il resto diviso per il numero di pareggi. Questo può essere piccolo quanto . Quando e sono coprimi, è possibile rendere i rifiuti arbitrariamente piccoli selezionando valori sufficientemente grandi di . Per i valori generali di eu d d R d - kNudd RdmodNugcd(R,N)RNdRNgcd(R,N)N/gcd(R,N)Rd−kNudRdmodNugcd(R,N)RNdRN, il calcolo è più complicato perché è necessario tenere conto della generazione di e separatamente, ma ancora una volta è possibile rendere i rifiuti arbitrariamente piccoli con gruppi abbastanza grandi.gcd(R,N)N/gcd(R,N)
In pratica, anche con numeri casuali relativamente inefficienti (ad esempio nella crittografia), raramente vale la pena fare qualsiasi cosa tranne un semplice campionamento del rifiuto, a meno che sia piccolo. Ad esempio, nella crittografia, dove è in genere una potenza di 2 e genere centinaia o migliaia di bit, la generazione di numeri casuali uniformi di solito procede mediante campionamento di rifiuto diretto nell'intervallo desiderato.R NNRN