为了响应this question,我运行了以下VBA实验:
Sub Test()
Dim i As Long, A As Variant
Dim count1 As Long, count2 As Long
ReDim A(1 To 10000)
For i = 1 To 10000
Randomize
A(i) = IIf(Rnd() < 0.5, 0, 1)
Next i
'count how often A(i) = A(i+1)
For i = 1 To 9999
If A(i) = A(i + 1) Then count1 = count1 + 1
Next i
For i = 1 To 10000
A(i) = IIf(Rnd() < 0.5, 0, 1)
Next i
'count how often A(i) = A(i+1)
For i = 1 To 9999
If A(i) = A(i + 1) Then count2 = count2 + 1
Next i
Debug.Print "First Loop: " & count1
Debug.Print "Second Loop: " & count2 & vbCrLf
End Sub
当我看到这样的输出时:First Loop: 5550
Second Loop: 4976
我非常确定自己知道发生了什么:VBA正在将系统时钟转换为较低分辨率(可能是微秒)的结果,这将导致Randomize
有时在循环中两次或更多次传递时产生相同的种子。在我最初的回答中,我什至自信地断言了这一点。但是随后我又运行了一些代码,并注意到输出有时是这样的:First Loop: 4449
Second Loop: 5042
过度播种仍会引起明显的自相关-但方向相反(且出乎意料)。具有相同种子的循环中的连续传递应该产生相同的输出,因此,我们应该看到连续值比偶然预测的更多地同意,而不比偶然预测的更多地不同。现在很好奇,我将代码修改为:
Sub Test2()
Dim i As Long, A As Variant
Dim count1 As Long, count2 As Long
ReDim A(1 To 10000)
For i = 1 To 10000
Randomize
A(i) = Rnd()
Next i
'count how often A(i) = A(i+1)
For i = 1 To 9999
If A(i) = A(i + 1) Then count1 = count1 + 1
Next i
For i = 1 To 10000
A(i) = Rnd()
Next i
'count how often A(i) = A(i+1)
For i = 1 To 9999
If A(i) = A(i + 1) Then count2 = count2 + 1
Next i
Debug.Print "First Loop: " & count1
Debug.Print "Second Loop: " & count2 & vbCrLf
End Sub
它总是提供以下输出:First Loop: 0
Second Loop: 0
似乎并非有时连续调用Randomize
有时会返回相同的种子(至少不足以产生变化)。但是,如果这不是自相关的来源,那是什么?而且-为什么有时它会表现为负自相关而不是正自相关?
最佳答案
仅部分答案,可以随意编辑和完成。
好吧,当您过度使用随机化功能时,显然存在相关性。
我尝试了以下代码,并使用了条件格式(值大于0.5的黑色填充),并且明显出现了模式(尝试对Randomize进行注释,以查看更“随机”的模式。(最好在20 pt列和10%的情况下看到)飞涨)
Function Rndmap()
Dim i As Long, j As Long
Dim bmp(1 To 512, 1 To 512) As Long
For i = 1 To 512
For j = 1 To 512
' Rnd -1 ' uncomment this line to get a big white and black lines pattern.
Randomize 'comment this line to have a random pattern
bmp(i, j) = IIf(Rnd() < 0.5, 0, 1)
Next j
Next i
Range(Cells(1, 1), Cells(512, 512)) = bmp
End Function
因此,尽管MSDN指出“对数字使用相同的值进行随机化不会重复前一个序列。”,这意味着如果计时器返回相同值的两倍,则Rnd应该保持相同的随机序列而无需复位,但仍然存在一些在幕后的链接。
一些截图:
仅Rnd():
使用随机化:
使用Rnd -1并随机化: