在VBA中重复随机变量

时间:2010-05-21 19:26:12

标签: vba random

如何使用randomize和rnd获取随机变量的重复列表?

通过重复列表,我的意思是如果你运行一个循环来获得10个随机数,列表中的每个随机数都是唯一的。此外,如果您再次运行此序列,您将获得与之前相同的10个随机数。

2 个答案:

答案 0 :(得分:13)

来自微软自己的口:

  

要重复随机数序列,请在使用带有数字参数的Randomize之前立即使用否定参数调用Rnd。

有关详细信息,请参阅here

整个部分:


说明

Rnd函数返回小于1但大于或等于零的值。

数字的值决定Rnd如何生成随机数:

对于任何给定的初始种子,生成相同的数字序列,因为对Rnd函数的每次连续调用都使用前一个数字作为序列中下一个数字的种子。

在调用Rnd之前,请使用不带参数的Randomize语句,使用基于系统计时器的种子初始化随机数生成器。

要在给定范围内生成随机整数,请使用以下公式:

Int((upperbound - lowerbound + 1) * Rnd + lowerbound)

此处,upperbound是范围内的最高数字,而lowerbound是范围中的最低数字。

注意 要重复随机数序列,请在使用带有数字参数的Randomize之前立即使用否定参数调用Rnd。使用具有相同数字值的Randomize不会重复前一个序列。


举例来说,如果将此代码放入Excel中,则每次运行时都会生成不同的数字:

Sub xx()
    ' x = Rnd(-1) '
    Randomize 10
    MsgBox (Rnd)
End Sub

但是,如果您取消注释x = Rnd(-1)行,则会在每次运行时生成相同的号码。

请注意,您必须执行两个事情。使用负参数调用Rnd并使用特定参数调用调用Randomize。改变其中任何一个都会给你一个不同的种子(因此顺序)。


编辑:

重新评论:

  

通过重复序列,我的意思是如果你运行一个循环来获得10个随机数,列表中的每个随机数都是唯一的。此外,如果您再次运行此序列,您将获得与以前相同的10个随机数。我所描述的是否有意义?

您现在还需要一条信息。你要求的不是随机数而是随机数。我将向您推荐我之前就如何执行此操作的问题here。您需要做的就是将洗牌算法与上面详述的种子设置相结合,您将拥有可重复的,独特的序列。


这里有一些代码可以显示它的实际效果。这个子程序的每次运行都会返回序列4 1 5 6 2 3 7 10 9 8,所以我认为这就是你所追求的,一个可重复的,“随机的”,独特的序列。如果您希望能够生成不同的序列(但仍以可重复的方式),则只需更改Randomize的值。

Option Explicit
Option Base 1

Sub xx()
    Dim x(10) As Integer
    Dim xc As Integer
    Dim xp As Integer
    Dim i As Integer
    Dim s As String

    For i = 1 To 10
        x(i) = i
    Next
    xc = 10

    i = Rnd(-1)
    Randomize 1

    s = "Values:"
    For i = 1 To 10
        xp = Int(Rnd * xc) + 1
        s = s & " " & CStr(x(xp))
        x(xp) = x(xc)
        xc = xc - 1
    Next i

    MsgBox (s)
End Sub

答案 1 :(得分:0)

实际上,不需要使用Randomize来重复Rnd伪随机序列。

看看下面的代码行。它只输出10个随机数:

MsgBox Join(Array(Rnd(), Rnd(), Rnd(), Rnd(), Rnd(), Rnd(), Rnd(), Rnd(), Rnd(), Rnd()), vbCrLf)

如果是第一次运行(即使用初始种子),或者在重置VBA代码执行后(以这种方式重新初始化)运行,则输出如下:

0,7055475
0,533424
0,5795186
0,2895625
0,301948
0,7747401
1,401764E-02
0,7607236
0,81449
0,7090379

该序列以任何VBA或VBS代码返回作为初始种子。

要重复该序列,您只需通过将负数传递给Rnd函数作为参数来指定种子:

MsgBox Join(Array(Rnd(-8716085), Rnd(), Rnd(), Rnd(), Rnd(), Rnd(), Rnd(), Rnd(), Rnd(), Rnd()), vbCrLf)

甚至是这样:

Rnd -16184694
MsgBox Join(Array(Rnd(), Rnd(), Rnd(), Rnd(), Rnd(), Rnd(), Rnd(), Rnd(), Rnd(), Rnd()), vbCrLf)

与任何其他序列相同,只需将种子指定为Rnd参数。