1. 程式人生 > >使用python實現偽隨機數生成器

使用python實現偽隨機數生成器

在前兩天學習了使用python實現偽隨機數的方法,今天是時候來做一個總結了。
首先要說明的是什麼是隨機數,真正的隨機數是使用物理現象產生的:比如擲錢幣、骰子、轉輪、使用電子元件的噪音、核裂變等等。產生這些隨機數的方法有很多種,而這些產生隨機數的方法就稱為隨機數生成器。像前面說的由物理現象所產生的隨機數發生器叫做物理性隨機數發生器,它們的缺點是技術要求比較高。
但是在我們的實際生活中廣泛應用的是偽隨機數生成器,所謂的“偽”就是假的的意思,也就是說並不是真正的隨機數。那麼這些隨機數是怎麼實現的呢?這些數字是由固定的演算法實現的,是有規律可循的,並不能實現真正的“隨機”,但是它們具有類似於隨機數的統計特徵。這樣的發生器叫做偽隨機數發生器。
實現偽隨機數的方法有很多種,如:平方取中法,線性同餘法等方法。
下面主要介紹的是線性同餘法,如C的rand函式和JAVA的java.util.Random類就是使用該方法實現的,其公式為:
<

rNew = (a*rOld + b) % (end-start)

其中, a稱為乘數,b稱為增量,(end-start)稱為模數,它們均為常數。
然後設定rOld = rNew,一般要求使用者指定種子數rOld(也稱為seed),當然也可以自由選擇a和b,但是兩個數如果選擇不好,可能會影響數字的隨機性 ,所以一般令:
a=32310901
b=1729
這樣使得生成的隨機數最均勻。下面我是用的將種子自定義設為999999999。程式碼如下:

def myrandint(  start,end,seed=999999999   ):
    a=32310901     #產生出的隨機數最均勻
    b=1729
    rOld=seed
    m=end-start
    while True:      #每呼叫一次這個myrandint函式,才生成一次隨機數  所以要惰性求值
        rNew = (a*rOld+b)%m
        yield rNew
        rOld=rNew
        
#模擬使用20個不同的種子來生成隨機數
for i in range(20):
    r = myrandint(1,10000,  i)
    #每個種子生成10個隨機數
    print('種子',i,'生成隨機數')
    for j in range(10):
        print( next(r),end=',' )
    print(      )
 

執行結果是使用20個不同的種子生成的隨機數。
但是,這樣將種子設為固定值是不合理的。

r = myrandint(1,10000,2)
print(r.__next__())
print(r.__next__())

執行結果為:
9993
6934
當再次執行程式碼:

r = myrandint(1,10000,2)
print(r.__next__())

執行結果仍然是:9993
這便不能體現隨機,因此常採用系統時間作為種子來實現該演算法。以上程式碼只需將seed設為系統時間便可以實現。