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

Swift arc4random()和arc4random_uniform()不是真正的随机?,swift,random,swift-playground,darwin,Swift,Random,Swift Playground,Darwin,我一直在使用arc4random()和arc4random_uniform(),我总是觉得它们不是完全随机的,例如,我从数组中随机选择值,但当我连续多次生成它们时,通常得到的值是相同的,所以今天我想用一个Xcode游乐场来看看这些函数是如何运行的,所以我首先测试arc4random\u uniform来生成一个介于0和4之间的数字,所以我使用了这个算法: import Cocoa var number = 0 for i in 1...20 { number = Int(arc4ra

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

import Cocoa

var number = 0

for i in 1...20 {
    number = Int(arc4random_uniform(5))
}
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))%)")
}
我已经运行了好几次,下面是如何判断价值观在大多数情况下是如何演变的:

因此,正如您所看到的,这些值不断增加和减少,一旦这些值达到最大值/最小值,它们通常会在某一特定时间内保持不变(参见第5步的第一个屏幕截图,在6个步骤中,值保持在3,问题是它一点也不奇怪,在我的测试中,函数实际上大部分时间都是这样运行的

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

下面是我的问题:

  • 为什么这个函数会以这种方式运行
  • 如何使它更随机
多谢各位

编辑:
最后,我做了两个令人惊讶的实验,第一个是真正的骰子:

让我惊讶的是,我不会说它是随机的,因为我看到的模式与arc4random()和arc4randomèu uniform()中描述为非随机的模式相同,正如Jean-Baptiste Yunès指出的,人类不善于看到一个数字序列是否真的是随机的。

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

import Cocoa

var number = 0

for i in 1...20 {
    number = Int(arc4random_uniform(5))
}
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次


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

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


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

这取决于您所说的随机性是什么意思

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

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


其他的选择可能包括使用a对数组中的事物进行排序,或者使用算法对值进行相等的分布。

我不太同意人类不善于检测随机性的观点。 如果你在掷6对骰子后获得1-1-2-2-3-3-4-4-5-5-6-6,你会满意吗?但是骰子的频率是完美的

这正是我在使用arc4random或arc4random_统一函数时遇到的问题。 多年来,我一直在开发一款双陆棋应用程序,它是基于word champions玩家训练的神经网络。我知道它比任何一款都好,但很多用户认为它是作弊。我有时也有疑问,所以我决定自己掷所有的骰子

我对arc4random一点也不满意,即使频率还行。 我总是掷几个骰子,结果会导致不可接受的情况,例如:同一个玩家连续五次掷双骰子,等待12圈(24个骰子),直到前6圈出现

易于测试(C代码):

也许arc4random不喜欢在短时间内被调用两次

所以我尝试了几种解决方案,最后选择了这段代码,它在arc4random_uniform之后运行第二级随机化:

int CFRandomDice ()
{
    int __result = -1 ;

    BOOL __found = NO ;

    while ( ! __found )
    {
        // random int big enough but not too big
        int __bigint = arc4random_uniform ( 10000 ) ;

        // Searching for the first character between '1' and '6'
        // in the string version of bigint :

        NSString * __bigString = @( __bigint ).stringValue ;

        NSInteger __nbcar = __bigString.length ;
        NSInteger __i = 0 ;

        while ( ( __i < __nbcar ) && ( ! __found ) )
        {
            unichar __ch = [__bigString characterAtIndex:__i] ;
            if ( ( __ch >= '1' ) && ( __ch <= '6' ) )
            {
                __found = YES ;
                __result = __ch - '1' + 1 ;
            }
            else
            {
                __i++ ;
            }
        }
    }

    return ( __result ) ;
}

<>现在我确信玩家不会抱怨……< /p>检查一下:@ Mrunar他们使用的函数不是我做的吗?一系列随机数可以包含一个重复序列的子序列……如果你掷硬币并交替的头和尾,你会认为“足够随机”吗??这是一个视觉伪影!尝试使用另一种视觉效果,例如圆中的随机点…你将能够更容易地观察到分布是“均匀的”。在你的“1D”中绘图,只是尝试在值之间交换,例如,拿一个图形,将线换成值6,将线换成值0,你会发现图形几乎是一样的!当你告诉我,如果我使用骰子,我会感到惊讶…这正是我刚才所做的,是的,我感到惊讶:如果我看到了这个图形,但没有知道这是一个骰子,我会说它是一个糟糕的随机发生器。不管怎样,我仍然感到惊讶的是,在我的随机世代中,val