如何批量随机化布尔值

时间:2015-03-23 15:10:41

标签: swift random

我想用纯粹的swift随机化10,000个布尔值并获得所有那些真实的总和。

5 个答案:

答案 0 :(得分:3)

可以使用reduce()函数方便地计算总和:

/// Return the result of repeatedly calling `combine` with an
/// accumulated value initialized to `initial` and each element of
/// `sequence`, in turn.
func reduce<S : SequenceType, U>(sequence: S, initial: U, combine: (U, S.Generator.Element) -> U) -> U

如果您只对这笔款项感兴趣:

let sum = reduce(0 ..< 10000, 0) { (sum, _) in sum + Int(arc4random_uniform(2)) }

如果你需要Bool数组和总和:

let bools = map (0 ..< 10000) { _ in arc4random_uniform(2) == 1 }
let sum = reduce(bools, 0) { $0 + Int($1) }

更新:正如Zaph在下面建议的那样,应该使用全部32位 arc4random...函数减少函数调用次数。这将是

let numberOfInt32 = 10000 / 32
let remainingBits = 10000 % 32

let sum = reduce(0 ..< numberOfInt32, 0) { (sum, _) in sum + NumberOfSetBits(arc4random()) }
    + NumberOfSetBits(arc4random_uniform(UInt32(1 << remainingBits)))

其中NumberOfSetBits()计算设置位数并且是a https://stackoverflow.com/a/109025/1187415到Swift的翻译:

func NumberOfSetBits(var i : UInt32) -> Int {
    i = i - ((i >> 1) & 0x55555555)
    i = (i & 0x33333333) + ((i >> 2) & 0x33333333)
    return Int((((i + (i >> 4)) & 0x0F0F0F0F) &* 0x01010101) >> 24)
}

(另见Rikkle's answer 这是在平均时间发布...)

答案 1 :(得分:2)

如果你不需要保存你的布尔和

var sum = 0
for i in 1...10000{
   if(arc4random_uniform(2) == 1)
      sum++
}

如果你想保存它们

var sum = 0
var boolArrays = []
for i in 1...10000{
   if(arc4random_uniform(2) == 1){
      sum++
      boolArray.addObject(true)
   }
   else{
       boolArray.addObject(false)
   }
}

答案 2 :(得分:2)

我建议在10,000/8字节数上使用arc4random_buf,然后应用横向加法(或&#34;汉明重量&#34;)来总结该系列字节中的所有位,一次一个int(32位)。有关汉明重量的良好伪代码,请参阅https://stackoverflow.com/a/109025/1401029

这应该比包含随机函数的任何循环结构明显更快更干净。

答案 3 :(得分:1)

  

arc4random_uniform()将返回均匀分布的随机数   小于upper_bound。

var countTrue : Int = 0
var countFalse : Int = 0
for i in 1 ... 10000 {
    if (arc4random_uniform(2) == 1) {
         countTrue++
    } else {
         countFalse++
    }
}

NSLog("count true: \(countTrue), count false: \(countFalse)")

答案 4 :(得分:0)

如果您不需要实际的布尔值,则总和会有N=10000p=1/2的二项分布。对于那么大的N,它与高斯平均值N*p和方差N*p*(1-p)(对应于标准偏差50)几乎无法区分,四舍五入到最近整数。您可以使用Box-Muller方法生成标准法线,并按如下方式进行缩放:

import Cocoa

let uniform_denom = UInt32(RAND_MAX) + 1

func u0_1() -> Double {
  var num = arc4random_uniform(uniform_denom)
  return Double(num) / Double(uniform_denom)
}

func gaussian() -> (Double, Double) {
  var d = sqrt(-2.0 * log(u0_1()))
  var theta = 2.0 * M_PI * u0_1()
  return (d * cos(theta), d * sin(theta))  // 2-tuple of std normals
}

var sum = 5000 + Int(round(50.0 * gaussian().0))  // scale to mean = 5000, std-dev = 50