Weighted randomisation in swift?

I have a function that calculates a random genotype. At the moment all genes are equally likely. In reality, some genes are more likely than others. How can I change my function to be more realistic? I have attached some example percentages (they don't add up yet)

Code Block     func calculateGenotype() {
    //grey 10% of "G" appearing, 90% chance of "g" appearing
    greGenotype = ["G", "g"][Int.random(in:0...1)]+["G", "g"][Int.random(in:0...1)]
    //single tobiano 5% of "To" appearing, 95% of "to" appearing
    tobGenotype = ["To", "to"][Int.random(in:0...1)]+["To", "to"][Int.random(in:0...1)]
    }


Answered by OOPer in 650983022
I do not know if such functionality is included in the Standard Library or any other frameworks of Apple's, but you can write it by yourself.
Code Block
func weightedRandom<Value>(weightedValues: (value: Value, weight: Double)...) -> Value {
let rnd = Double.random(in: 0.0...100.0)
var accWeight = 0.0
for (value, weight) in weightedValues {
accWeight += weight
//print(rnd, accWeight)
if rnd <= accWeight {
return value
}
}
//If the sum of weights is less the 100%, the last value is returned
return weightedValues.last!.value
}
let greGenotype: String
let tobGenotype: String
greGenotype =
weightedRandom(weightedValues: ("G", 10), ("g", 90)) +
weightedRandom(weightedValues: ("G", 10), ("g", 90))
tobGenotype =
weightedRandom(weightedValues: ("To", 5), ("to", 95)) +
weightedRandom(weightedValues: ("To", 5), ("to", 95))
print(greGenotype, tobGenotype)

(Seems 10 to 90 or 5 to 95 is too small for debugging.)
Accepted Answer
I do not know if such functionality is included in the Standard Library or any other frameworks of Apple's, but you can write it by yourself.
Code Block
func weightedRandom<Value>(weightedValues: (value: Value, weight: Double)...) -> Value {
let rnd = Double.random(in: 0.0...100.0)
var accWeight = 0.0
for (value, weight) in weightedValues {
accWeight += weight
//print(rnd, accWeight)
if rnd <= accWeight {
return value
}
}
//If the sum of weights is less the 100%, the last value is returned
return weightedValues.last!.value
}
let greGenotype: String
let tobGenotype: String
greGenotype =
weightedRandom(weightedValues: ("G", 10), ("g", 90)) +
weightedRandom(weightedValues: ("G", 10), ("g", 90))
tobGenotype =
weightedRandom(weightedValues: ("To", 5), ("to", 95)) +
weightedRandom(weightedValues: ("To", 5), ("to", 95))
print(greGenotype, tobGenotype)

(Seems 10 to 90 or 5 to 95 is too small for debugging.)
Thanks, this works :)
Weighted randomisation in swift?
 
 
Q