2009-03-15 12 views
14

UtilizzandoObjective C: Modulo pregiudizi

value = arc4random() % x 

Come posso evitare o eliminare pregiudizi modulo?

Grazie a tutti.

BTW, almeno secondo Wikipedia, modulo bias è un problema durante la programmazione di giochi d'azzardo .

+1

consideri ri-marcatura risposta di Zoidberg come quella corretta, in quanto è la risposta corretta in base alla canonica gli autori di arc4random(). – MikeyWard

+2

[Che cos'è il bias del modulo] (http://stackoverflow.com/questions/10984974/why-do-people-say-there-is-modulo-bias-when-using-a-random-number-generator)? – bobobobo

risposta

14

arc4random restituisce un numero intero senza segno a 32 bit (da 0 a 2 -1).

Probabilmente non ci sarà alcun bias del modulo per x abbastanza piccolo. Tuttavia, se si vuole essere veramente sicuri, fare questo:

y = 2 p cui 2 p-1 < x ≤ 2 p

val = arc4random() % y; 
while(val >= x) 
    val = arc4random() % y; 
+0

Prego. =) –

+0

Se ricordo, c'è qualcosa di simile nel generatore di numeri casuali di Python. –

+3

Mi capita di inciampare nello stesso compito, l'implementazione C può essere trovata in OpenBSD 'arc4random_uniform()' in [src/sys/dev/rnd.c] (http://www.openbsd.org/cgi-bin/cvsweb/ src/sys/dev/rnd.c? rev = 1.140; content-type = text% 2Fplain) – SashaN

2

Se il valore massimo di arc4random mod x è maggiore di x, ignorare qualsiasi valore maggiore del più grande arc4random-max mod x, chiamando nuovamente arc4random.

4
u_int32_t maxValue = ~((u_int32_t) 0);  // equal to 0xffff... 
maxValue -= maxValue % x;     // make maxValue a multiple of x 
while((value = arc4random()) >= maxValue) { // loop until we get 0 ≤ value < maxValue 
} 
value %= x; 

anche se a meno che non si sta utilizzando qualsiasi x meno di un milione (o più) Io non mi preoccuperei a questo proposito

1
u_int32_t maxValue = ~((u_int32_t) 0);  // equal to 0xffff... 
maxValue -= maxValue % x;     // make maxValue a multiple of x 
while((value = arc4random()) >= maxValue) { // loop until we get 0 ≤ value < maxValue 
} 
value %= x; 

Un po 'pedante obiezione alla risposta di cobbal. Funziona, rimuove il bias del modulo, ma rifiuta più valori del necessario. Il caso più estremo è x = 2^31. Tutti i valori di arc4random() dovrebbero essere accettati qui, ma il codice come scritto rifiuterà la metà di essi.

Invece, aggiungi 1 all'inizializzazione di maxValue (che lo colloca a 2^32 in modo da utilizzare un int di 64 bit), quindi è corretto. Puoi anche evitare di usare un int di 64 bit. Prova in anticipo se 2^32% x == 0, se è così tutti i valori arc4random() sono accettabili e puoi saltare il ciclo, altrimenti puoi mantenere maxValue a 32 bit sottraendo 2^32% x all'inizializzazione.

47

Utilizzare arc4random_uniform(x). Questo lo fa per te.

Secondo la pagina man:

arc4random_uniform() restituirà un numero casuale uniformemente distribuito meno di upper_bound. arc4random_uniform() è consigliato su costruzioni come arc4random() % upper_bound in quanto evita "modulo bias" quando il limite superiore non è una potenza di due.

+5

Questa risposta è migliore di quella accettata. –

-1

Utilizzare il metodo seguente. Evita "modulo bias" ed è veloce su iphone. Risparmiarti alcuni cicli di CPU.

SE volete 4-7:

(random()/(float)RAND_MAX)*3+4 

o se volete 0-8

(random()/(float)RAND_MAX)+8 
+0

'random()' non è un generatore di numeri casuali sicuro, non usarlo! – dchest