让我们说我正在计算1到100的随机数。我希望数字随机选择,但是我可以设置偏差,更可能选择中心。因此,如果我做随机样本可以说一千次,那么将会更频繁地选择中心数字。它选择中心的数量应该基于我在didHitChanceOf函数中设置的数字。这样做的最佳方式是什么?
我目前的代码没有做到这一点,甚至是随机性的
当前非偏向随机数代码(Swift 3)
extension Int
{
static func random(range: ClosedRange<Int> ) -> Int
{
var offset = 0
if range.lowerBound < 0 // allow negative ranges
{
offset = abs(range.lowerBound)
}
let mini = UInt32(range.lowerBound + offset)
let maxi = UInt32(range.upperBound + offset)
return Int(mini + arc4random_uniform(maxi - mini)) - offset
}
}
func didHitChanceOf(chance: Double) -> Bool{
let random = Int.random(range: 0...100)
if(Double(random) < chance){ //If the conversion rate is 20%, then only 20% of the time will the random number be less than the conversion rate.
return true
}else{
return false
}
}
var adwordsClicks = 500
let adwordsConversionRate = 20
var adwordsConversions = 0
for _ in 0...adwordsClicks {
if(didHitChanceOf(chance: adwordsConversionRate) == true){
adwordsConversions = adwordsConversions + 1
}
}
答案 0 :(得分:6)
您可以使用GameKit中的GKGaussianDistribution
(也称为正态分布)来执行此操作。您需要2个参数:mean
(&#34;中心&#34;您想要的)和deviation
(它应该从中心传播多远):
import GameKit
func random(count: Int, in range: ClosedRange<Int>, mean: Int, deviation: Int) -> [Int] {
guard count > 0 else { return [] }
let randomSource = GKARC4RandomSource()
let randomDistribution = GKGaussianDistribution(randomSource: randomSource, mean: Float(mean), deviation: Float(deviation))
// Clamp the result to within the specified range
return (0..<count).map { _ in
let rnd = randomDistribution.nextInt()
if rnd < range.lowerBound {
return range.lowerBound
} else if rnd > range.upperBound {
return range.upperBound
} else {
return rnd
}
}
}
用法和测试:
let arr = random(count: 1_000_000, in: 0...100, mean: 70, deviation: 10)
let summary = NSCountedSet(array: arr)
for i in 0...100 {
print("\(i): \(summary.count(for: i))")
}
您可以看到70左右的值具有最高计数