目录
1 VBA中直接使用 rnd,是一个公式计算出来的模拟(伪随机)
3.3 rnd 和 rnd(-1) rnd(0) rand(1) 参数负数,零,和正数
3.4 直接用 rnd 和 rnd(-1) rnd(0) rand(1) 的总结
3.6 配合 randomize 直接用 rnd 和 rnd(-1) rnd(0) rand(1) 参数负数,零,和正数
3.7 配合 randomize 直接用 rnd 和 rnd(-1) rnd(0) rand(1)的总结
总结前置
- 如果想永远生成相同的随机数,就用rnd(-1) 但是这么做没意义吧?
- 如果想每次生成的随机数,本次程序运行结束前都一样,下次计算时不一样。就用 randmize 和 rnd(0)
- 如果想永远生成不同的随机数,无论是序列内,还是在不同的环境重新运行都不同,就用 randmize 和 rnd(1) 或 randmize 和 rnd 缺省就可以。
1 VBA中直接使用 rnd,是一个公式计算出来的模拟(伪随机)
- 什么叫伪随机
- 随机数的生成是使用一个写定的公式,来模拟随机的感觉
- 但是这个生成随机数的模拟公式 f(f(f(1))) 受第一个数影响很大,一般称为随机种子
- 如何形象的理解伪随机数
- 你就想象,你的随机函数,每次生成的都是 3.1415926 这个序列,先给你生成3 1 4 1 5 9 2 6.。。。,下次你重新,还是从3 1 4 1 5 9 2 6.。。。 开始
2 伪随机数会带来什么问题:永远是同一组随机数
- 下面是一个对比测试
- 都是同一段代码
- 最左边的是,多次运行代码的结果,看起来每次随机的结果都不同
- 中间的,是每次执行后,都点停止运行,再点开始运行,这样loop循环操作出的结果
- 最右边的,是每次执行后,点3次运行,然后点停止运行,这样loop循环操作出的结果
- 对比后,发现很神奇的结果
- VBA里默认用 rnd 随机,如果一直运行,其实能一直往下随机
- 但是随机出的这一串数其实每次都是固定的从第1个 0.7055475 开始,可以说这1串数是固定的!也就是,每次重新开始,都是这一串相同的数组!
- 也就是相当于,不同的时候,重新开始执行这个 rnd 随机,随机结果永远相同!
- 也就是这段代码,每次在不同的时候重新开始运行,总是生成相同的随机数序列!!!!
Sub t1111()
Debug.Print Rnd
End Sub
- 参考内容
- Rnd函数在产生随机数的时候,并不是真正的随机,而是通过一定的公式计算产生的随机,现在我们把那个计算产生随机数的公式叫做f(x),第一个x取值为1
- 那么便会产生第一个随机数f(1),第2个随机数是在第一个随机数的基础上产生的即f(f(1)),依次类推,第3个随机数是f(f(f(1)))
- 不难发现,第一个数1,对于产生的一系列随机数是非常重要的,这个1,我们称之为种子数,一个种子数就对应一系列的随机数,如果种子数不发生变化,那么便会生成一系列相同的随机数
- 这段分析来自网上一个大神写的
- 哪位能举几个例子说明一下 VBA中Randomize的作用,_百度知道
3 关于 rnd 的语法
3.1 基本语法
- excel里用 rand() 和 randbetween()
- VBA里用 rnd
Rnd[(number)]
可选的 number 参数是 Single 或任何有效的数值表达式。
返回值
如果 number 的值是 Rnd 生成
小于 0 每次都使用 number 作为随机数种子得到的相同结果。
大于 0 序列中的下一个随机数。
等于 0 最近生成的数。
省略 序列中的下一个随机数。
说明
Rnd 函数返回小于 1 但大于或等于 0 的值。
number 的值决定了 Rnd 生成随机数的方式。
对最初给定的种子都会生成相同的数列,因为每一次调用 Rnd 函数都用数列中的前一个数作为下一个数的种子。
在调用 Rnd 之前,先使用无参数的 Randomize 语句初始化随机数生成器,该生成器具有根据系统计时器得到的种子。
为了生成某个范围内的随机整数,可使用以下公式:
Int((upperbound - lowerbound + 1) * Rnd + lowerbound)
这里,upperbound 是随机数范围的上限,而 lowerbound 则是随机数范围的下限。
注意 若想得到重复的随机数序列,在使用具有数值参数的 Randomize 之前直接调用具有负参数值的 Rnd。使用具有同样 number 值的 Randomize 是不会得到重复的随机数序列的。
3.2 基本用法
- 要知道 rnd() 是左闭右开区间 [0,1)
- 如果要生成 a~b之间的随机数,一般是 int(a+ (b-a+1)*rnd())
- 如果数太大,要给数加上 clng(a)
3.3 rnd 和 rnd(-1) rnd(0) rand(1) 参数负数,零,和正数
- 测试下面3段代码,发现只有 rnd(2 ) 每次随机都变化
Sub TEST1()
For i = 1 To 3
Debug.Print Rnd(-1)
Next
End Sub
Sub TEST2()
For i = 1 To 3
Debug.Print Rnd(0)
Next
End Sub
Sub TEST3()
For i = 1 To 10
Debug.Print Rnd(2)
Next
End Sub
- 最左边是test1的结果
- 其次是test2的结果
- 第3个是test3 一直点运行的结果
3.4 直接用 rnd 和 rnd(-1) rnd(0) rand(1) 的总结
小于 0 每次都使用 number 作为随机数种子得到的相同结果。
大于 0 序列中的下一个随机数。
等于 0 最近生成的数。
省略 序列中的下一个随机数。
- rnd(-1) 永远 生成相同的随机数,无论是继续生成下一个,还是重新开始随机
- rnd(0) 生成最近生成的数。也就是继续生成下一个的时候会是一样的上次的,重新开始也是一样,因为 永远=第1个。
- rnd(1) 生成下一个数,且生成的下一个会不一样。但是,重新开始会依然从相同的第1个开始,也就是序列相同。
- rnd 同正数的
3.4 如何每次随机都得到相同的随机序列呢?
3.4.1 使用 rnd 负数
- 如果想每次随机都得到相同的随机序列
- 只要在随机前加一句 rnd 负数
- 并且 rnd -1 和 rnd -2 得出的随机序列还不相同
Sub TEST33()
Rnd -2 '修改不同负数可得到可重复的不同序列的随机数
For i = 1 To 5
Debug.Print Rnd()
Next
Debug.Print "OK"
End Sub
3.4.2 一些其他的可能性
- 配合 rnd 负数
- 还可以加 randomize 数字(但是 只有randomize 数字 这一句无法实现这个效果的)
- 实现随机序列的不同
Sub TEST34()
Rnd -2 '修改不同负数可得到可重复的不同序列的随机数
Randomize 888 '修改不同的Randomize 随机种子,随机序列也不同
For i = 1 To 5
Debug.Print Rnd()
Next
Debug.Print "OK"
End Sub
3.4.3 randomize 的意义
- randomize 是随机种子
- randomize 语句 默认= randomize timer
- 系统的时间作为默认的随机种子,即使你不写
3.6 配合 randomize 直接用 rnd 和 rnd(-1) rnd(0) rand(1) 参数负数,零,和正数
Sub TEST4()
Randomize
For i = 1 To 3
Debug.Print Rnd(-1)
Next
End Sub
Sub TEST5()
Randomize
For i = 1 To 3
Debug.Print Rnd(0)
Next
End Sub
Sub TEST6()
Randomize
For i = 1 To 3
Debug.Print Rnd(2)
Next
End Sub
- 最左边是test4的结果 (无论点不点停止后开始,永远都是相同的)
- 第2个是test5 一直点运行的结果(rnd(1) 会取上次的,这次运行过程中会一样)
- 第3个是test5的结果,同上句运行结果,为什么每次内的相同,每次外的不同。因为加了 randmize 每次重新运行时会重新随机随机种子
- 第4个是test6点一次运行,点一次停止后的结果,每次都会不一样
- 第5个是test6 点一次运行,点一次停止后的结果,每次都会不一样
3.7 配合 randomize 直接用 rnd 和 rnd(-1) rnd(0) rand(1)的总结
- randomize 默认缺省会用时间当随机种子
- randomize timer
- 是一样的
- randomize 和 rnd(-1) 永远 生成相同的随机数,无论是继续生成下一个,还是重新开始随机。 参数-1 作用巨大
- randomize 和 rnd(0) 生成最近生成的数。也就是继续生成下一个的时候会是一样的上次的。重新开始也不一样,因为随机种子不同的,下次的第1个不同了!
- 但是往下运行,还是会生成和这次结束前上1个一样的
- randomize 和 rnd(1) 生成下一个数,且生成的下一个会不一样。但是,重新开始因为随机种子不同,会完全一样的随机序列。
- randomize 和rnd 同正数的
4 总结
- 如果想永远生成相同的随机数,就用rnd(-1) 但是这么做没意义吧?
- 如果想每次生成的随机数,本次程序运行结束前都一样,下次计算时不一样。就用 randmize 和 rnd(0)
- 如果想永远生成不同的随机数,无论是序列内,还是在不同的环境重新运行都不同,就用 randmize 和 rnd(1) 或 randmize 和 rnd 缺省就可以。