问题描述
针对这个问题,我进行了以下VBA实验:
In response to this question I ran the following VBA experiment:
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
当我看到这样的输出时:
When I saw output like this:
First Loop: 5550
Second Loop: 4976
我非常确定我知道发生了什么:VBA正在将系统时钟转换为较低分辨率(可能是微秒)的结果,结果将导致Randomize
有时在两次或更多次传递中产生相同的种子.环形.在我最初的回答中,我什至自信地断言了这一点.但是后来我又运行了一些代码,发现输出有时是这样的:
I was pretty sure that I knew what was happening: VBA was converting the system clock into something of lower resolution (perhaps microsecond) which as a consequence would lead to Randomize
sometimes producing identical seeds in two or more passes through the loop. In my original answer I even confidently asserted this. But then I ran the code some more and noticed that the output was sometimes like this:
First Loop: 4449
Second Loop: 5042
过度播种仍会引起明显的自相关-但方向相反(且出乎意料).具有相同种子的连续遍历循环应该产生相同的输出,因此我们应该看到连续值比偶然预测的更多地同意,而不比偶然预测的更多地反对.
The overseeding is still causing a noticeable autocorrelation -- but in the opposite (and unexpected) direction. Successive passes through the loop with the same seed should produce identical outputs, hence we should see successive values agreeing more often than chance would predict, not disagreeing more often than chance would predict.
现在很好奇,我将代码修改为:
Curious now, I modified the code to:
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
有时返回相同的种子的情况(至少不足以产生变化).
It seems that it isn't the case that successive calls to Randomize
sometimes returns the same seed (at least not often enough to make a difference).
但是,如果这不是自相关的源头,那是什么?而且-为什么有时它会表现为负自相关而不是正自相关?
But if that isn't the source of the autocorrelation -- what is? And -- why does it sometimes manifest itself as a negative rather than a positive autocorrelation?
推荐答案
仅部分答案,可以随意编辑和完成.
Partial answer only, fell free to edit and complete.
好吧,当您过度使用Randomize函数时,显然存在相关性.
Well, there is clearly a correlation when you overuse the Randomize function.
我尝试了以下代码,并使用了条件格式(值> 0.5的黑色填充),并且明显出现了模式(尝试对Randomize进行注释,以查看更多的随机"模式.(最好在20 pt列中看到)和10%缩放)
I tried the following code, with a conditional formatting (black fill for values >0.5), and there is clearly patterns appearing (try to comment the Randomize to see a more "random" pattern. (best seen with 20 pt columns and 10% zoom)
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应该保持相同的随机序列而不进行重置,幕后还有一些链接.
So while the MSDN states that "Using Randomize with the same value for number does not repeat the previous sequence.", implying that if the Timer returns twice the same value, the Rnd should keep on the same random sequence without reseting, there is still some behind the scene link..
一些屏幕截图:
仅Rnd():
使用随机化:
使用Rnd -1并随机化:
Using Rnd -1 and Randomize:
这篇关于如何理解由于过多植入RNG导致的自相关?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!