来自于一份PSO代码,PSO中须要初始化粒子位置和速度。html
众所周知,Matlab中的rand()函数产生的是伪随机数,但通常用来也能够接受。可是,若是咱们知道伪随机数的初始状态,那么产生的伪随机数是惟一肯定的。问题来了,Matlab每次启动会重置rand()和randn()的初始状态(重置为0),也就是说,你产生的随机数会出现两次随机数如出一辙的状况,如:算法
1 >> rand('state',0) 2 >> rand(3,1) 3
4 ans =
5
6 0.9501
7 0.2311
8 0.6068
9
10 >> rand(3,1) 11
12 ans =
13
14 0.4860
15 0.8913
16 0.7621
17
18 >> rand('state',0) 19 >> rand(3,1) 20
21 ans =
22
23 0.9501
24 0.2311
25 0.6068
能够看到,第三次产生随机数,由于初始状态都是0,因此产生了彻底同样的随机数!
设定初始状态的好处是,只须要保存那时的初始状态再运行一遍程序你就能够重现以前的计算过程和结果。dom
缺点是虽然程序使用了随机数,但因为(每次启动后)初始状态同样,实际运行出来倒是相同的重复过程,你须要人工设定一个保证随机性的初始状态。函数
计算机系统中的随机数都是伪随机数,是经过一个算法连续产生的,知道上一个随机数,下一个随机数就肯定,已知从给定的某个数开始,后面连续的随机数序列都已经肯定,咱们使用随机数就好像从这个序列中(也叫随机数流)中取数字使用,为了增长随机数的随机程度,和可控性,用rand('state',X)来设置随机数流的状态,就像C语言中随机数的seed,一旦给一个X值,那么后面的随机数流就肯定,为了增长随机性,这里用当前时间数码sum(clock)做为随机数的状态,clock返回一个6个元素的向量分辨是年月日时分秒,sum加起来就做为随机数的状态,由于你每次运行程序的时间不一样,因此获得的随机数序列就不一样单独使用这句时,改变了随机数流的状态,可是尚未使用,因此不产生任何变量。但这个算法有一个问题是,若是计算机太快的话,仍然会生成相同随机数。可考虑用 rand('state',sum(clock)*rand(1))。spa
rand('seed', S)
rand('state', S)
rand('twister', S)
S是表示初始状态的整数。
seed、state、twister就比较奇怪,使人捉摸不透,不知道该选用哪一个。这其实是产生随机数的不一样算法。code
seed表示采用v4版本的随机数产生器,state是v5版本的随机数产生器,最后的twister用的则是Mersenne Twister随机数产生器。htm
那么具体该用哪个呢?在新版本的语法说明中,Matlab给出了答案:前两个随机数产生器都是“flawed”,推荐你们使用twister随机数产生器。blog
此外,MathWorks公司意识到了这几个参数可能会产生误导,因而在新版本(2012及之后)的Matlab中更新了语法。class
rng(1);
A = rand(2,2);
rng('shuffle')
A = rand(2,2);
新版的Matlab默认采用Mersenne Twister随机数产生器,rng(S) 函数表示设定初始状态,rng('shuffle') 表示随机分配一个初始状态。变量
因此如今只须要记住rng()函数设置初始状态,而后用rand产生随机数就能够了。
然而,有时咱们只须要“真正”的伪随机数(不重复!),如何获得?
用2012版本以后的用户比较方便,在产生随机数以前使用rng('shuffle')洗一下就能够(shuffle是洗牌的意思)。
对于旧版本的用户,还不支持rng函数。之前通常是rand('state',sum(100*clock))来根据当前时间设定初始状态,但时间始终是递增的,并且变化幅度相对来讲很小,效果不是很好。
有不少人用别的方式设定初始状态(如rand('twister', fix(mod(1e11*(sum(clock)-2009), 2^31)));),为简便起见,我的推荐采用新版Matlab中rng函数语法,即rand('twister',mod(floor(now*8640000),2^31-1)) ,这样能够产生的不一样的随机数。采用这种办法大约每497天种子才会重复一次,通常使用的话足够了。
参考文献:百度知道
http://cn.mathworks.com/help/matlab/math/generate-random-numbers-that-are-different.html