首先让我说明我想要完成的事情:
在使用drand48(),rand()和arc4random()进行了相当多的实验之后,我目前已经决定使用rand()获取随机数,并使用srand()进行种子设定。这是一个从我正在做的事情简化的小例子:
let seed: UInt32 = 10
srand(seed)
let start = 0
let end = 100
let randomNumber = Double(rand()) % (end + 1 - start) + start
这很有效。给定相同的种子,出现相同的随机数。执行多个randomNumber计算会产生多个不同的随机数。通过srand重新播种开始"随机性"再次。
唯一的缺点是rand()不是均匀分布的。事实上,我总是最终会得到一组在大多数情况下呈线性增长的数字。
听起来arc4random_uniform会产生更多的均匀随机输出,但是根据我的研究,它不可能为arc4random播种,因为它在第一次被调用时种子化并且不一定&# 34;设计"在外部播种。
所以我的问题;是否有更好的srand()/ rand()替代方案,它仍然会为给定的种子提供相同的输出,但这些输出更均匀地分布?
谢谢, - 亚当
答案 0 :(得分:15)
我知道" GameKit"听起来它只适用于游戏,但它包含一个严重的随机数生成系统。我建议你看看GKMersenneTwisterRandomSource和GKRandomDistribution。 GKMersenneTwisterRandomSource
采用随机种子(如果您愿意),GKRandomDistribution
类实现统一分布。一起使用,它们完全符合您的要求。
import GameKit
// The Mersenne Twister is a very good algorithm for generating random
// numbers, plus you can give it a seed...
let rs = GKMersenneTwisterRandomSource()
rs.seed = 1780680306855649768
// Use the random source and a lowest and highest value to create a
// GKRandomDistribution object that will provide the random numbers.
let rd = GKRandomDistribution(randomSource: rs, lowestValue: 0, highestValue: 100)
// Now generate 10 numbers in the range 0...100:
for _ in 1...10 {
print(rd.nextInt())
}
print("---")
// Let's set the seed back to the starting value, and print the same 10
// random numbers.
rs.seed = 1780680306855649768
for _ in 1...10 {
print(rd.nextInt())
}
答案 1 :(得分:3)
事实证明,srand / rand组合适合我的需要,导致结果不出现的问题"均匀分布"我自己的逻辑是一个错误。
作为参考,基本上我正在做的是这个(实际上它要复杂得多,但出于演示目的):
let start = 0
let end = 100
for x in 0..<10 {
let seed = UInt32(x)
srand(seed)
let randomNumber = Double(rand()) % (end + 1 - start) + start
// Do something with random number
}
以上面更简单的形式编写,问题变得明显。我在循环的每次迭代中重新播种,种子值只是线性递增。因此,随机结果也呈线性递增。
简单的解决方案是不对每个循环迭代重新播种,而是在循环之前播种一次。例如:
let start = 0
let end = 100
let seed = UInt32(100)
srand(seed)
for x in 0..<10 {
let randomNumber = Double(rand()) % (end + 1 - start) + start
// Do something with random number
}
通过这个简单的更改,结果值似乎在示例中使用的0到100范围内有些均匀分布。我无法确定是否有更均匀的&#34;这样做的方式,但我认为,因为我已经读过arc4random是&#34;远远优于&#34; drand / rand / erand / etc函数用于统一随机数生成,但至少这似乎可以满足我的需求。
如果其他人提出更好的方法来完成我所追求的目标,我会暂时搁置这个问题。