

1. 前言
Matlab产生的随机数是伪随机数。所谓伪随机数,就是指
- 给定一个初始状态
- 按照某种方法或规律
而产生的随机数。
只要初始状态和方法相同,产生的随机数就是相同的。
以下试验均通过 Matlab R2016a 进行,适用于函数 rand, randi, 和 randn 。用到的参考资料有,
参考资料1:https://www.mathworks.com/help/matlab/math/generate-random-numbers-that-are-repeatable.html#bt1uhlr
参考资料2:https://www.mathworks.com/help/matlab/ref/rng.html
参考资料3:https://www.mathworks.com/help/matlab/ref/randstream.html
参考资料4:https://www.mathworks.com/help/matlab/math/why-do-random-numbers-repeat-after-startup.html
如果你想直接产生可重复的随机数,而没有耐心看前面的部分,请直接跳到第5节。
2. 对应的术语
在Matlab中:
- 初始状态对应:种子和状态向量,
- 某种方法或规律对应:随机数生成器类型。
3. 如何设置随机数种子与随机数生成器类型
3.1 随机数生成器类型有哪些
可供设置的随机数生成器类型见下表,来自参考资料2。
3.2 种子的取值范围
目前,好像没有找到资料指明种子的取值范围。事实上Matlab的错误提示给出了答案:小于 2^32 的非负整数。
3.3 设置语法
设置种子的值与随机数生成器类型语法如下:
rng(seed); %保持当前的随机数生成器类型,设置种子值为seed rng(100); %保持当前的随机数生成器类型,设置种子值为100 rng(seed, generator); %设置种子值为100,并指定随机数生成器为generator rng(0,'twister'); %设置种子值为0,并指定随机数生成器为Mersenne Twister
设置建议:一般说来,虽然只指定种子而不改变类型也是可以的,但是建议同时设定两个,因为参考资料1中提到:
翻译过来就是:
如果你想要:
保证你的代码在当前及今后的 Matlab 版本中都运行一致,
保证你在之前的 Matlab 版本中写的代码并运行的结果与现在一致,
保证你的代码在运行其他代码之后的运行结果一致,
请同时指定种子与生成器类型。
4. Matlab启动时的默认行为
Matlab启动时的默认行为如下:
– 设置种子类型为Mersenne Twister
– 设置种子为0
– 设置状态向量为一默认的初始值
这三句可通过 rng(0,’twister’) 实现,等效于 rng(‘default’) 。
等效的原因是在通过rng(seed)或rng(seed, generator)设置种子时,Matlab会自动重置状态向量为初始状态。
因此实际上,Matlab每次启动之后,同样的代码产生的随机数应该是一样的(当然要在同一个版本的Matlab下,因为不同版本的Matlab可能会调整随机数生成器类型与默认种子)。
5. 如何产生可重复的随机数
一个简单有效而比较愚蠢的办法,运行完代码之后重启Matlab,重启后下一次运行的结果和上一次保证是一模一样的。
另一个办法,根据刚才所述,只要设置好种子值与随机数生成器类型即可。
例如,如果在产生随机数前,我都运行这个命令
rng(1,'twister');
那么每次运行rand(5)产生的结果都是
>> rng(1,'twister'); >> rand(5) ans = 0.4170 0.0923 0.4192 0.6705 0.8007 0.7203 0.1863 0.6852 0.4173 0.9683 0.0001 0.3456 0.2045 0.5587 0.3134 0.3023 0.3968 0.8781 0.1404 0.6923 0.1468 0.5388 0.0274 0.1981 0.8764
这个办法有一个缺陷:作用是全局的。设置完种子值和随机数生成器类型,之后产生的所有随机数都会受此影响。
如果我想要同时产生多个随机数流,并在某个时刻只对某个或某几个随机数流进行重置,则需要用到下面的 RandStream 函数。
6. RandStream的用法
以后再说,客官可以先看看参考资料3。
客官留步,在这儿说点什么吧~