如何批量随机化布尔值
How to randomize booleans in bulk
我想随机化纯 swift 中的 10,000 个布尔值,然后得到所有为真值的总和。
如果你不需要保存你的布尔值
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)
}
}
可以使用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)) }
如果需要布尔数组和求和:
let bools = map (0 ..< 10000) { _ in arc4random_uniform(2) == 1 }
let sum = reduce(bools, 0) { [=12=] + Int() }
更新: 正如 Zaph 在下面建议的那样,应该利用来自
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()
计算设置位的数量并且是
到 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)
}
(另见
同时发布...)
arc4random_uniform() will return a uniformly distributed random number
less than 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)")
我建议在 10,000/8 个字节上使用 arc4random_buf
,然后应用横向加法(或 "Hamming Weight")来总结该系列字节中的所有位,一个 int (32 位)一次。有关汉明权重的良好伪代码,请参阅 。
这应该比任何包含随机函数的循环结构更快更清晰。
如果您不需要实际的布尔值,总和服从 N=10000
和 p=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
我想随机化纯 swift 中的 10,000 个布尔值,然后得到所有为真值的总和。
如果你不需要保存你的布尔值
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)
}
}
可以使用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)) }
如果需要布尔数组和求和:
let bools = map (0 ..< 10000) { _ in arc4random_uniform(2) == 1 }
let sum = reduce(bools, 0) { [=12=] + Int() }
更新: 正如 Zaph 在下面建议的那样,应该利用来自
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()
计算设置位的数量并且是
到 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)
}
(另见
arc4random_uniform() will return a uniformly distributed random number less than 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)")
我建议在 10,000/8 个字节上使用 arc4random_buf
,然后应用横向加法(或 "Hamming Weight")来总结该系列字节中的所有位,一个 int (32 位)一次。有关汉明权重的良好伪代码,请参阅 。
这应该比任何包含随机函数的循环结构更快更清晰。
如果您不需要实际的布尔值,总和服从 N=10000
和 p=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