arc4random()和arc4random_uniform()不是真的随机吗?

Tre*_*vör 12 random darwin swift swift-playground

我一直在使用arc4random()arc4random_uniform(),我总觉得它们不是完全随机的,例如,我是从一个数组中随机选择值,但是当我生成它们时,经常出现的值是相同的连续多次,所以今天我认为我会使用Xcode游乐场来看看这些函数是如何表现的,所以我首先测试arc4random_uniform来生成0到4之间的数字,所以我使用了这个算法:

import Cocoa

var number = 0

for i in 1...20 {
    number = Int(arc4random_uniform(5))
}
Run Code Online (Sandbox Code Playgroud)

我跑了几次,这里是大多数时候价值观的变化:
在此输入图像描述 在此输入图像描述

因此,您可以看到值重复增加和减少,并且一旦值处于最大值/最小值,它们通常会在特定时间内保持不变(请参阅第5步中的第一个屏幕截图,值在6期间保持为3)步骤,问题是它一点都不寻常,在我的测试中,函数实际上大部分时间都是这样.

现在,如果我们看一下arc4random(),它基本上是一样的:
在此输入图像描述 在此输入图像描述

所以这是我的问题:

  • 为什么这个函数会以这种方式运行?
  • 如何让它更随机?

谢谢.

编辑:
最后,我做了两个令人惊讶的实验,第一个带有真正的骰子:
在此输入图像描述
让我感到惊讶的是,我不会说它是随机的,因为我看到了与arc4random()和arc4random_uniform()所描述的非随机相同的模式,所以Jean-BaptisteYunè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))%)")
}
Run Code Online (Sandbox Code Playgroud)

要查看每个数字出现的次数,并且有效地数字是随机生成的,例如,这里是控制台的一个输出:
0出现99次.
1次出现了97次.
2次出现了78次.
3次出现了80次.
4次出现了87次.
5次出现107次.
6次出现了86次.
7次出现了97次.
8次出现了100次.
9次出现91次.
10次​​出现了78次.

所以这绝对没问题

编辑#2:我再次制作了更多掷骰子的骰子实验,这对我来说仍然令人惊讶:
在此输入图像描述

Jea*_*nès 9

算法不能生成真正的随机数字序列.它们只能产生伪随机数字序列(看似随机序列的东西).因此,根据所选择的算法,"随机性"的质量可能会有所不同.arc4random()序列的质量通常被认为具有良好的随机性.

你无法直观地分析序列的随机性......人类检测随机性非常糟糕!他们倾向于找到一些没有的结构.在您的图表中没有什么真正的伤害(除了6个连续的罕见子序列,但这是随机性,有时会发生异常情况).如果您使用骰子生成序列并绘制其图形,您会感到惊讶.请注意,只有20个数字的样本无法根据其随机性进行严格分析,您需要更大的样本.

如果您需要其他类型的随机性,您可以尝试使用/dev/random伪文件,每次读入时都会生成一个随机数.序列是由计算机中发生的混合算法和外部物理事件生成的.

  • 要非常小心,测试随机性是一个真正的挑战!我建议你阅读http://en.wikipedia.org/wiki/Randomness_tests.有很多软件套件可以测试这个...... (2认同)