vba - 如何理解因 RNG 播种过多而导致的自相关?

标签 vba random

回复 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 的情况。有时会返回相同的种子(至少不会经常产生影响)。
但如果这不是自相关的来源——是什么?而且——为什么它有时会表现为负的而不是正的自相关?

最佳答案

仅部分答案,可自由编辑和完成。

好吧,当您过度使用 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 声明“使用 Randomize 与 number 的相同值不会重复之前的序列。”,这意味着如果 Timer 返回两次相同的值,则 Rnd 应该保持相同的随机序列而不重置,仍然有一些幕后链接..

一些截图:

仅 Rnd():
Rnd

使用随机化:
randomize

使用 Rnd -1 和随机化:
Rnd -1

关于vba - 如何理解因 RNG 播种过多而导致的自相关?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41102399/

相关文章:

random - 兰德的样本和独立样本特征有什么区别?

random - Math.random具体值corona sdk

Python:比 numpy 的 random.choice() 更快的替代品?

excel - 循环中的 URLDownloadToFile 函数不起作用,因为即使没有要下载的文件,该函数也会返回 0

vba - 根据字符串内容对组下的每个字符串进行分类(1 次)? (Excel)

vba - 根据 A 列中的匹配索引替换 C 列中的字符串

vba - 从组合框中选择项目

vba - 打印每行副本之前的最后一行和单元格区域的发送值

c++ - 初始化后相同的内存地址

c++ - 使用 boost 分离随机数生成器类的接口(interface)和实现