ios - 生成具有给定分布的随机数

标签 ios swift coding-style

看看这个问题:

Swift probability of random number being selected?

最上面的答案建议使用 switch 语句来完成这项工作。然而,如果我要考虑大量的情况,代码看起来就很不优雅;我有一个巨大的 switch 语句,其中的代码在每种情况下都一遍又一遍地重复。

当您需要考虑大量概率时,是否有更好、更干净的方法以一定的概率选择随机数? (大约 30)

最佳答案

这是一个受各种影响强烈的 Swift 实现 回复Generate random numbers with a given (numerical) distribution .

对于 Swift 4.2/Xcode 10 及更高版本(内嵌说明):

func randomNumber(probabilities: [Double]) -> Int {

    // Sum of all probabilities (so that we don't have to require that the sum is 1.0):
    let sum = probabilities.reduce(0, +)
    // Random number in the range 0.0 <= rnd < sum :
    let rnd = Double.random(in: 0.0 ..< sum)
    // Find the first interval of accumulated probabilities into which `rnd` falls:
    var accum = 0.0
    for (i, p) in probabilities.enumerated() {
        accum += p
        if rnd < accum {
            return i
        }
    }
    // This point might be reached due to floating point inaccuracies:
    return (probabilities.count - 1)
}

示例:

let x = randomNumber(probabilities: [0.2, 0.3, 0.5])

以 0.2 的概率返回 0,以 0.3 的概率返回 1, 2 的概率为 0.5。

let x = randomNumber(probabilities: [1.0, 2.0])

以 1/3 的概率返回 0,以 2/3 的概率返回 1。

<小时/>

对于Swift 3/Xcode 8:

func randomNumber(probabilities: [Double]) -> Int {

    // Sum of all probabilities (so that we don't have to require that the sum is 1.0):
    let sum = probabilities.reduce(0, +)
    // Random number in the range 0.0 <= rnd < sum :
    let rnd = sum * Double(arc4random_uniform(UInt32.max)) / Double(UInt32.max)
    // Find the first interval of accumulated probabilities into which `rnd` falls:
    var accum = 0.0
    for (i, p) in probabilities.enumerated() {
        accum += p
        if rnd < accum {
            return i
        }
    }
    // This point might be reached due to floating point inaccuracies:
    return (probabilities.count - 1)
}
<小时/>

对于Swift 2/Xcode 7:

func randomNumber(probabilities probabilities: [Double]) -> Int {

    // Sum of all probabilities (so that we don't have to require that the sum is 1.0):
    let sum = probabilities.reduce(0, combine: +)
    // Random number in the range 0.0 <= rnd < sum :
    let rnd = sum * Double(arc4random_uniform(UInt32.max)) / Double(UInt32.max)
    // Find the first interval of accumulated probabilities into which `rnd` falls:
    var accum = 0.0
    for (i, p) in probabilities.enumerate() {
        accum += p
        if rnd < accum {
            return i
        }
    }
    // This point might be reached due to floating point inaccuracies:
    return (probabilities.count - 1)
}

关于ios - 生成具有给定分布的随机数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52425225/

相关文章:

ios - 恢复 App 时获取 launchOptions

oop - 封装: allow accessing of fields of any other than the current receiver object

java - IntelliJ 中的自动格式化行

ios - IOS FB.init上的PhoneGap/Cordova 2.2.0 Facebook插件失败

ios - 如何在单元格中设置视频的缩略图

iphone - 为什么即使我覆盖 touchesMoved :withEvent:? UIScrollView 的子类仍然滚动

ios - InstagramKit 收到的ValidAccessTokenFromURL 不起作用

ios - Swift:dispatch_async is effect is inconsistent for animation

c - 混合标准和精确宽度类型

ios - WKWebView:html 内容中的 mailto 链接未打开邮件应用程序