有時(shí)為了某些測(cè)試需求,需要仿真產(chǎn)生一些數(shù)據(jù)。 這時(shí),我們可以通過調(diào)取指令或自行編寫程序來生成這些隨機(jī)數(shù)據(jù)。
以下以博途為例,簡(jiǎn)要說明了隨機(jī)數(shù)產(chǎn)生的幾種方式:
一、讀取系統(tǒng)時(shí)間的納秒作為隨機(jī)數(shù)
以固定周期直接將系統(tǒng)時(shí)間中的納秒輸出到對(duì)應(yīng)變量。
系統(tǒng)時(shí)間中的納秒為UDINT類型,轉(zhuǎn)為INT后,丟棄了高字部分
監(jiān)視實(shí)時(shí)的系統(tǒng)時(shí)間,取其中的納秒(NANOSECOND,1秒=10^9納秒)
監(jiān)視一下生成的隨機(jī)數(shù)的范圍:-32258—32751(5分鐘)
后續(xù)可繼續(xù)對(duì)此數(shù)據(jù)處理,縮放到需要的區(qū)間。
二、由LGF庫(官方提供的通用函數(shù)庫)內(nèi)的隨機(jī)數(shù)程序生成
該指令原理也是采用納秒,不過處理過程更加細(xì)化、完善。
LGF庫
隨機(jī)數(shù)生成程序如下(只貼了其中關(guān)鍵的計(jì)算過程):
REGION Calculating random number
// 將納秒轉(zhuǎn)換為雙字以便尋址單個(gè)字節(jié)
#tempNanoSecondInDWord := UDINT_TO_DWORD(#tempTime.NANOSECOND);
// 以片段訪問方式將納秒進(jìn)行字節(jié)交換
#tempRandomValue.%B3 := #tempNanoSecondInDWord.%B0;
#tempRandomValue.%B2 := #tempNanoSecondInDWord.%B1;
#tempRandomValue.%B1 := #tempNanoSecondInDWord.%B2;
#tempRandomValue.%B0 := #tempNanoSecondInDWord.%B3;
// 隨機(jī)數(shù)標(biāo)準(zhǔn)化
#tempNormReal := UDINT_TO_REAL(DWORD_TO_UDINT(#tempRandomValue)) / UDINT_TO_REAL(#MAX_UDINT);
// 隨機(jī)數(shù)縮放
#LGF_RandomRange_Real := ((#tempNormReal * (#maxValue - #minValue) + (#minValue)));
#error := false;
#status := #STATUS_FINISHED_NO_ERROR;
#subfunctionStatus := #SUB_STATUS_NO_ERROR;
// ENO mechanism is not used
ENO := TRUE;
END_REGION
在主程序中調(diào)用,可設(shè)置上下限
三、線性同余法(LCG,Linear Congruential Method)
該方法的核心是以下遞歸公式:
RandNum =(A * RandNum + B)% M
A、B、M均為常數(shù),其中A是 乘數(shù) ,B是 增量 ,M是 模數(shù) ,RandNum是 初始值 ,A、C、M的取值是保證產(chǎn)生高質(zhì)量隨機(jī)數(shù)的關(guān)鍵。
可以看出,每次新產(chǎn)生的隨機(jī)數(shù)都跟上一次的數(shù)有關(guān)系。 隨機(jī)數(shù)序列中的初始值,我們通常叫做種子。 隨機(jī)數(shù)的產(chǎn)生需要設(shè)置種子,否則隨機(jī)數(shù)的結(jié)果每次運(yùn)行都將一樣。 通常,我們使用系統(tǒng)時(shí)間的納秒作為種子(某些將此作為缺省設(shè)置),這在一定程度上保證了種子的唯一性。
由于計(jì)算過程最后是對(duì)M取余數(shù),余數(shù)的范圍就是0—(M-1),這決定了產(chǎn)生的隨機(jī)數(shù)是有周期性的。 M的大小決定了最大周期的長短,一般取值域的最大值,而A和B也會(huì)影響周期。 A、B、M的選取多種多樣,只要保證產(chǎn)生的隨機(jī)數(shù)有較好的均勻性和隨機(jī)性即可。
FC塊,變量定義為雙整型。 模數(shù)M可以取值域最大值2^32
種子seed可以采用系統(tǒng)時(shí)間或自行設(shè)置
隨機(jī)數(shù)曲線
線性同余法的初始值一旦確定,輸出的序列將固定。 而當(dāng)獲取某些隨機(jī)數(shù)序列后,其初始值以及A、B、M也會(huì)被反向計(jì)算出來。
對(duì)于其缺點(diǎn),可以考慮以下改進(jìn)方式,每產(chǎn)生n個(gè)數(shù),將當(dāng)前時(shí)鐘值MOD M得到的余數(shù)作為新的種子。
四、平方取中法
平方取中法由馮·諾依曼提出,它的原理是:首先取一個(gè)2s位的整數(shù)(種子),平方,得4s位整數(shù),然后取此4s位中間的2s位作為下次運(yùn)算的種子。 重復(fù)該過程,即可得到一個(gè)隨機(jī)數(shù)序列。 (序列中每個(gè)數(shù)縮放至0.0—1.0范圍內(nèi))
例如:取種子365,平方得133225,高位補(bǔ)0,取中間1332,平方得1774224,高位補(bǔ)0,取7742,以此類推.........
#RandInt := SQR(#Seed);
#Seed := (#RandInt MOD 1000000 - #RandInt MOD 100) / 100;
#RandReal := DINT_TO_REAL(#Seed) / 9999.0;
隨機(jī)數(shù)測(cè)試結(jié)果
在實(shí)踐中,這種方法其實(shí)并不好用。 很難說明取什么種子才能保證足夠長的周期。 以種子123為例,在40多個(gè)周期后,種子末位便退化產(chǎn)生了00,之后的隨機(jī)數(shù)成了固定的幾個(gè)數(shù)值,周期極短。 該算法也有改進(jìn)空間。
梅森旋轉(zhuǎn)算法_Mersenne Twister
梅森旋轉(zhuǎn)算法可以產(chǎn)生高質(zhì)量的偽隨機(jī)數(shù),且效率高效,彌補(bǔ)了以上偽隨機(jī)數(shù)生成器的不足和缺陷。 它在C++、Python等編程語言中均有應(yīng)用。
理解該算法前需要先了解許多前置名詞,線性反饋移位寄存器、級(jí)、反饋函數(shù)、抽頭序列、本原多項(xiàng)式...... 實(shí)在有興趣的可以搜索一下。 我,放棄了。
說到隨機(jī)數(shù),不禁想到了因果律:果由因生、有依空立 、事待理成。
所謂的“隨機(jī)”,大概不過是事物發(fā)展中的個(gè)體因?yàn)?a target="_blank">信息偏差,產(chǎn)生的局限認(rèn)知。
-
plc
+關(guān)注
關(guān)注
5016文章
13388瀏覽量
465422 -
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
7145瀏覽量
89583 -
仿真
+關(guān)注
關(guān)注
50文章
4124瀏覽量
133998 -
程序
+關(guān)注
關(guān)注
117文章
3796瀏覽量
81418 -
隨機(jī)數(shù)
+關(guān)注
關(guān)注
0文章
18瀏覽量
12048
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論