Sono stato con arc4random() e arc4random_uniform() e ho sempre avuto la sensazione che non era esattamente a caso, per esempio, ero casualmente valori scegliendo tra una vasta gamma ma spesso i valori che sono venuti sono stati gli stessi quando li ho generati più volte di seguito, quindi oggi ho pensato che avrei usato un parco giochi Xcode per vedere come si comportano queste funzioni, quindi prima testò arc4random_uniform per generare un numero compreso tra 0 e 4, quindi Ho usato questo algoritmo:arc4random() e arc4random_uniform() non sono casuali?
import Cocoa
var number = 0
for i in 1...20 {
number = Int(arc4random_uniform(5))
}
E l'ho eseguito volte Veral, e qui è come i valori si stanno evolvendo la maggior parte del tempo:
Quindi, come potete vedere i valori sono in aumento e in diminuzione più volte, e una volta che i valori sono al massimo/minimo, spesso ci rimani durante un certo tempo (vedi la prima schermata al quinto passaggio, il valore rimane a 3 durante 6 passaggi, il problema è che non è affatto insolito, la funzione si comporta in questo modo in gran parte del tempo nei miei test
Ora, se guardiamo arc4random()
, è fondamentalmente lo stesso:
Così qui sono le mie domande:
- Perché questa funzione si comporta in questo modo?
- Come renderlo più casuale?
Grazie.
EDIT:
Infine, ho fatto due esperimenti che sono stati sorprendenti, il primo con un vero e dadi:
Cosa mi ha sorpreso è che non avrei detto che è stata casuale, poiché stavo vedendo lo stesso tipo di schema che è descritto come non casuale per arc4random() & arc4random_uniform(), così come ha sottolineato Jean-Baptiste Yunès, gli umani non sono bravi a vedere se una sequenza di numeri è davvero casuale.
ho anche voluto fare un esperimento più "scientifica", così ho fatto questo algoritmo:
import Foundation
var appeared = [0,0,0,0,0,0,0,0,0,0,0]
var numberOfGenerations = 1000
for _ in 1...numberOfGenerations {
let randomNumber = Int(arc4random_uniform(11))
appeared[randomNumber]++
}
for (number,numberOfTimes) in enumerate(appeared) {
println("\(number) appeard \(numberOfTimes) times (\(Double(numberOfGenerations)/Double(numberOfTimes))%)")
}
per vedere quante volte ogni numero è apparso, e in modo efficace i numeri sono generati casualmente, per esempio, ecco un output dalla console:
0 apparso 99 volte.
1 apparso 97 volte.
2 apparso 78 volte.
3 apparso 80 volte.
4 apparso 87 volte.
5 è apparso 107 volte.
6 apparso 86 volte.
7 apparso 97 volte.
8 è apparso 100 volte.
9 apparso 91 volte.
10 apparso 78 volte.
quindi è sicuramente OK
EDIT # 2: ho fatto di nuovo l'esperimento a dadi con più cilindri, ed è ancora così sorprendente per me:
Controlla questo: http://stackoverflow.com/questions/56648/whats-the-best-way-to-shuffle-an-nsmutablearray – Mrunal
@Mrunal Non stanno usando le stesse funzioni di me? –
@Mrunal Il mio problema non riguarda come sostituire elementi in un array, ma solo come generare numeri veramente casuali. :) –