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

时间:2022-01-15 13:28:41

I have been using arc4random() and arc4random_uniform() and I always had the feeling that they wasn't exactly random, for example, I was randomly choosing values from an Array but often the values that came out were the same when I generated them multiple times in a row, so today I thought that I would use an Xcode playground to see how these functions are behaving, so I first tests arc4random_uniform to generate a number between 0 and 4, so I used this algorithm :

我一直使用arc4random()和arc4random_uniform()和我总感觉他们不是完全随机的,例如,我是随机选择的值从一个数组但经常出来的值是相同的,当我连续多次生成它们,所以今天我想我要使用一个Xcode操场去看这些功能是如何表现的,所以我第一次测试arc4random_uniform生成一个数字0和4之间,所以我使用这个算法:

import Cocoa

var number = 0

for i in 1...20 {
    number = Int(arc4random_uniform(5))
}

And I ran it several times, and here is how to values are evolving most of the time :
arc4random()和arc4random_uniform()不是真正的随机?arc4random()和arc4random_uniform()不是真正的随机?

我试了好几次,以下是如何衡量价值的

So as you can see the values are increasing and decreasing repeatedly, and once the values are at the maximum/minimum, they often stay at it during a certain time (see the first screenshot at the 5th step, the value stays at 3 during 6 steps, the problem is that it isn't at all unusual, the function actually behaves in that way most of the time in my tests.

所以你可以看到值增加,减少反复,一旦在最大/最小值,他们经常呆在它在特定的时间(见截图在第五届的第一步,值保持在3 6步骤,问题是,它不是不寻常,函数实际上表现在大部分时间在我的测试中。

Now, if we look at arc4random(), it's basically the same :
arc4random()和arc4random_uniform()不是真正的随机?arc4random()和arc4random_uniform()不是真正的随机?

现在,如果我们看看arc4random(),它基本上是一样的:

So here are my questions :

我的问题是:

  • Why is this function behaving in this way ?
  • 为什么这个函数是这样的?
  • How to make it more random ?
  • 如何使它更随机?

Thank you.

谢谢你!

EDIT :
Finally, I made two experiments that were surprising, the first one with a real dice :
arc4random()和arc4random_uniform()不是真正的随机?
What surprised me is that I wouldn't have said that it was random, since I was seeing the same sort of pattern that as described as non-random for arc4random() & arc4random_uniform(), so as Jean-Baptiste Yunès pointed out, humans aren't good to see if a sequence of numbers is really random.

编辑:最后,我做了两个实验,令人吃惊的是,第一个真正的骰子:使我感到惊奇的是,我不会说,这是随机的,自从我看到同样的模式,作为描述为随机arc4random()& arc4random_uniform(),以便让-巴蒂斯特·尼斯指出,人类并不好,看一个数字序列是随机的。

I also wanted to do a more "scientific" experiment, so I made this algorithm :

我也想做一个更“科学”的实验,所以我做了这个算法:

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))%)")
}

To see how many times each number appeared, and effectively the numbers are randomly generated, for example, here is one output from the console :
0 appeared 99 times.
1 appeared 97 times.
2 appeared 78 times.
3 appeared 80 times.
4 appeared 87 times.
5 appeared 107 times.
6 appeared 86 times.
7 appeared 97 times.
8 appeared 100 times.
9 appeared 91 times.
10 appeared 78 times.

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

So it's definitely OK ????

所以it's绝对好的????

EDIT #2 : I made again the dice experiment with more rolls, and it's still as surprising to me :
arc4random()和arc4random_uniform()不是真正的随机?

编辑#2:我再次做了骰子实验,有了更多的卷,这对我来说仍然是令人惊讶的:

2 个解决方案

#1


8  

A true random sequence of numbers cannot be generated by an algorithm. They can only produce pseudo-random sequence of numbers (something that looks like a random sequence). So depending on the algorithm chosen, the quality of the "randomness" may vary. The quality of arc4random() sequences is generally considered to have a good randomness.

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

You cannot analyze the randomness of a sequence visually... Humans are very bad to detect randomness! They tend to find some structure where there is no. Nothing really hurts in your diagrams (except the rare subsequence of 6 three in-a-row, but that is randomness, sometimes unusual things happens). You would be surprised if you had used a dice to generate a sequence and draw its graph. Beware that a sample of only 20 numbers cannot be seriously analyzed against its randomness, your need much bigger samples.

你无法直观地分析一个序列的随机性……人类很难发现随机性!他们倾向于找到一些没有的结构。在您的图中没有什么真正有害的(除了罕见的6个三排的子序列,但这是随机的,有时会发生不寻常的事情)。如果您使用骰子生成序列并绘制其图形,您会感到惊讶。注意,一个只有20个数字的样本不能被认真分析,因为它的随机性,你需要更大的样本。

If you need some other kind of randomness, you can try to use /dev/random pseudo-file, which generate a random number each time you read in. The sequence is generated by a mix of algorithms and external physical events that ay happens in your computer.

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

#2


4  

It depends on what you mean when you say random.

这取决于你说的随机是什么意思。

As stated in the comments, true randomness is clumpy. Long strings of repeats or close values are expected.

如评论所述,真正的随机性是笨拙的。需要长串的重复或关闭值。

If this doesn't fit your requirement, then you need to better define your requirement.

如果这不符合您的需求,那么您需要更好地定义您的需求。

Other options could include using a shuffle algorithm to dis-order things in an array, or use an low-discrepancy sequence algorithm to give a equal distribution of values.

其他选项可能包括使用一种洗牌算法对数组中的内容进行无序排序,或者使用一种低差异序列算法来给出相同的值分布。

#1


8  

A true random sequence of numbers cannot be generated by an algorithm. They can only produce pseudo-random sequence of numbers (something that looks like a random sequence). So depending on the algorithm chosen, the quality of the "randomness" may vary. The quality of arc4random() sequences is generally considered to have a good randomness.

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

You cannot analyze the randomness of a sequence visually... Humans are very bad to detect randomness! They tend to find some structure where there is no. Nothing really hurts in your diagrams (except the rare subsequence of 6 three in-a-row, but that is randomness, sometimes unusual things happens). You would be surprised if you had used a dice to generate a sequence and draw its graph. Beware that a sample of only 20 numbers cannot be seriously analyzed against its randomness, your need much bigger samples.

你无法直观地分析一个序列的随机性……人类很难发现随机性!他们倾向于找到一些没有的结构。在您的图中没有什么真正有害的(除了罕见的6个三排的子序列,但这是随机的,有时会发生不寻常的事情)。如果您使用骰子生成序列并绘制其图形,您会感到惊讶。注意,一个只有20个数字的样本不能被认真分析,因为它的随机性,你需要更大的样本。

If you need some other kind of randomness, you can try to use /dev/random pseudo-file, which generate a random number each time you read in. The sequence is generated by a mix of algorithms and external physical events that ay happens in your computer.

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

#2


4  

It depends on what you mean when you say random.

这取决于你说的随机是什么意思。

As stated in the comments, true randomness is clumpy. Long strings of repeats or close values are expected.

如评论所述,真正的随机性是笨拙的。需要长串的重复或关闭值。

If this doesn't fit your requirement, then you need to better define your requirement.

如果这不符合您的需求,那么您需要更好地定义您的需求。

Other options could include using a shuffle algorithm to dis-order things in an array, or use an low-discrepancy sequence algorithm to give a equal distribution of values.

其他选项可能包括使用一种洗牌算法对数组中的内容进行无序排序,或者使用一种低差异序列算法来给出相同的值分布。