我一直在使用 arc4random() 和 arc4random_uniform() 我总觉得它们不是完全随机的,例如,我是 随机从一个数组中选择值,但当我连续多次生成它们时,得出的值通常是相同的,所以今天我想我会使用 Xcode playground 来查看这些函数的行为方式,所以我首先测试 arc4random_uniform 生成一个介于 0 和 4 之间的数字,所以我使用了这个算法:
import Cocoa
var number = 0
for i in 1...20 {
number = Int(arc4random_uniform(5))
}
我运行了好几次,下面是大多数时候值(value)观是如何演变的:
所以你可以看到数值在反复增加和减少,一旦数值处于最大值/最小值,它们通常会在一段时间内保持不变(参见第 5 步的第一个屏幕截图,该值保持在3 在 6 个步骤中,问题是它一点也不异常,在我的测试中,该函数实际上大部分时间都以这种方式运行。
现在,如果我们看一下 arc4random()
,它基本上是一样的:
所以这是我的问题:
- 为什么这个函数会这样?
- 如何让它更随机?
谢谢。
编辑:
最后,我做了两个令人惊讶的实验,第一个是真正的骰子:
让我感到惊讶的是,我不会说它是随机的,因为我看到了与 arc4random() 和 arc4random_uniform() 描述为非随机的相同类型的模式,Jean-Baptiste Yunès指出,人类并不善于观察数字序列是否真的是随机的。
我也想做一个更“科学”的实验,所以我做了这个算法:
import Foundation
var appeared = [0,0,0,0,0,0,0,0,0,0,0]
var numberOfGenerations = 1000
for _ in 1...numberOfGenerations {
let randomNumber = Int(arc4random_uniform(11))
appeared[randomNumber]++
}
for (number,numberOfTimes) in enumerate(appeared) {
println("\(number) appeard \(numberOfTimes) times (\(Double(numberOfGenerations)/Double(numberOfTimes))%)")
}
要查看每个数字出现了多少次,并且这些数字实际上是随机生成的,例如,这是控制台的一个输出:
0出现了99次。
1出现97次。
2出现了78次。
3出现80次。
4出现了87次。
5出现107次。
6出现了86次。
7出现了97次。
8出现100次。
9出现了91次。
10出现了78次。
所以肯定没问题😊
编辑 #2:我再次进行了更多掷骰子实验,但它仍然让我感到惊讶:
最佳答案
算法无法生成真正的随机数字序列。它们只能产生伪随机数字序列(看起来像随机序列的东西)。因此,根据所选算法的不同,“随机性”的质量可能会有所不同。 arc4random()
序列的质量通常被认为具有良好的随机性。
您无法直观地分析序列的随机性……人类很难检测到随机性!他们倾向于在没有的地方找到一些结构。在你的图表中没有什么真正的伤害(除了罕见的连续 6 个 3 的子序列,但这是随机的,有时会发生不寻常的事情)。如果您使用骰子生成序列并绘制其图形,您会感到惊讶。请注意,只有 20 个数字的样本无法针对其随机性进行认真分析,您需要更大的样本。
如果你需要一些其他的随机性,你可以尝试使用/dev/random
伪文件,它会在你每次读入时产生一个随机数。这个序列是由一个混合产生的在您的计算机中发生的算法和外部物理事件的集合。
关于swift - arc4random() 和 arc4random_uniform() 不是真正随机的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27813728/