2016-03-20 10 views
0

Ich lernte Zufallszahlengenerierung mit Swift und Gameplaykit. Werden im folgenden Code die Zahlen generiert, wenn ich die Zufallsliste initialisiere, und wenn ich nextInt anrufe, oder wenn der Zufallsgenerator faul erzeugt wird, wenn ich nextInt() aufrufe, gibt es einfach eine Stichprobe aus den bereits generierten Zahlen.Zufallszahlengenerierung mit GameplayKit

let rand = GKMersenneTwisterRandomSource()   // the generator can be specified 
let randomDist = GKRandomDistribution(randomSource: rand, lowestValue: 50, highestValue: 100) 
randomDist.nextInt() 

Antwort

2

Denken Sie daran, dass ein GKRandomDistribution jede darunter liegende randomizer nutzen kann - ist, dass nicht nur eine der GameplayKit GKRandomSource Klassen, aber jede Klasse, die implementiert das GKRandom Protokoll. Sie können also diese Frage selbst beantworten, indem Sie Ihre eigene Zufallsquelle implementieren und sehen, wie/wann ihre Methoden aufgerufen werden.

class LoggingRandomSource: GKRandom { 
    let source = GKARC4RandomSource() 
    @objc func nextInt() -> Int { 
     let num = source.nextInt() 
     print("nextInt: \(num)") 
     return num 
    } 
    @objc func nextIntWithUpperBound(upperBound: Int) -> Int { 
     let num = source.nextIntWithUpperBound(upperBound) 
     print("nextIntWithUpperBound: \(num)") 
     return num 
    } 
    @objc func nextUniform() -> Float { 
     let num = source.nextUniform() 
     print("nextUniform: \(num)") 
     return num 
    } 
    @objc func nextBool() -> Bool { 
     let flip = source.nextBool() 
     print("nextBool: \(flip)") 
     return flip 
    } 
} 

let rand = LoggingRandomSource() 
let randomDist = GKRandomDistribution(randomSource: rand, lowestValue: 50, highestValue: 100) 
randomDist.nextInt() 

Halten Sie mit diesem Trick erkunden Sie ein paar Dinge über die zufällige Verteilung Klassen feststellen:

  • GKRandomDistribution Anrufe nextIntWithUpperBound auf die zugrunde liegende Zufallsquelle einmal für jeden Aufruf an eine seiner Methoden. Dies ist sinnvoll, da die zugrunde liegende Quelle nextIntWithUpperBound als einheitlich angenommen wird, so dass GKRandomDistribution nur diesen uniformen Int zu seinem lowestValue - highestValue Bereich zuordnen muss.

  • GKGaussianDistribution führt zwei Aufrufe des zugrunde liegenden nextUniform für jeden Aufruf einer seiner Methoden. Das liegt daran, dass es viele Möglichkeiten gibt, einen Gauß'schen (aka normalen) zufälligen Wert zu erzeugen, wenn zwei gleichförmige zufällige Werte gegeben werden - siehe Box-Muller transform.

  • GKShuffledDistribution macht eine Reihe von Anrufen auf das darunter liegende nextIntWithUpperBound das erste Mal, wenn Sie es für eine Reihe stellen, aber man kann es für viele mehr stellen, ohne es wieder auf die zugrunde liegende Quelle aufrufen. Dies passt zu dem dokumentierten Verhalten dieser Distribution: Sie sorgt dafür, dass alle möglichen Werte in ihrem Bereich ausgeschöpft werden, bevor derselbe erneut wiederholt wird. Ein einfacher Weg, dies zu tun, besteht darin, alle diese Werte zu nehmen, ihre Reihenfolge zu mischen und dann bei jedem Aufruf einen Wert aus dem gemischten Pool zu ziehen, bis er leer ist.

Verwandte Themen