來自於一份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