Python STL random

來源:互聯網
上載者:User

標籤:軟體   initial   val   blog   程式   time()   故障分析   使用   選擇   

作用:實現了多種類型的偽隨機數產生器。

Python版本:1.4及以後版本

random模組基幹Mersenne IVister演算法提供了一個快速偽隨機數產生器。原先開發這個產生器是為了向蒙特卡洛類比產生輸入,Mersenne Twister演算法會產生有一個大周期的近均勻分 布的數,以適用於各種類型的應用。

產生隨機數

random()函數從所產生的序列返回下一個隨機的浮點數值。返回的所有值都落在0< n <1.0區間內。

import randomfor i in xrange(5):    print '%04.3f' % random.random(),print

重複運行這個程式會產生不同的數字序列。

0.929 0.100 0.906 0.075 0.439[Finished in 0.1s]

要產生一個指定數值區間內的數,則要使用uniform()。

import randomfor i in xrange(5):    print '%04.3f' % random.uniform(1, 100),print

傳入最小值和最大值,uniform()會使用公式min + (max - min) * random來調整random() 的傳回值。

4.679 66.794 19.423 44.725 5.482[Finished in 0.1s]
指定種子

每次調用random會產生不同的值,在一個非常大的周期之後數字才會重複。這對於產生惟一值或變化的值很有用,不過有些情況下可能需要提供相同的資料集,從而以相同的方式處理。對此,一種技術是使用一個程式來產生隨機值,並儲存這些隨機值,以便通過一個單獨的步驟另行處理。不過,這對於量很大的資料來說可能並不實用,所以random包含了一個seed() 函數,用來初始化偽隨機數產生器,使它能產生一個期望的值集。

import randomrandom.seed(1)for i in xrange(5):    print '%04.3f' % random.random(),print

種子(seed)值會控制產生偽隨機數所用公式產生的第一個值,由於公式是確定性,改變種子後也就設定了要產生的整個序列。seed的參數可以是任意可散列對象。預設為使用一個平台特定的隨機源(如杲有的話)。否則,如果沒有這樣一個隨機源,則會使用目前時間。

0.134 0.847 0.764 0.255 0.495[Finished in 0.1s]
儲存狀態

random使用的偽隨機演算法的內部狀態可以儲存,並用於控制後續各輪產生的隨機數,繼續產生隨機數之前恢複前一個狀態,這會減少由之前輸入得到重複的值或值序列的可能性。getstate函數會返回一些資料,以後可以用setstate利用這些資料重新初始化偽隨機數產生器。

import randomimport osimport cPickle as pickleif os.path.exists('state.dat'):    # Restore the previously saved state    print 'Found state.dat, initializing random module'    with open('state.dat', 'rb') as f:        state = pickle.load(f)    random.setstate(state)else:    # Use a well-known start state    print 'No state.dat, seeding'    random.seed(1)# Produce random valuesfor i in xrange(3):    print '%04.3f' % random.random(),print# Save state for next timewith open('state.dat', 'wb') as f:    pickle.dump(random.getstate(), f)# Produce more random valuesprint '\nAfter saving state:'for i in xrange(3):    print '%04.3f' % random.random(),print

getstate()返回的資料是一個實現細節,所以這個例子用pickle將資料儲存到一個檔案,不過可以把它當作一個黑盒。如果程式開始時這個檔案存在,則載入原來的狀態並繼續。每次運行時都會在儲存狀態之前以及之後產生一些數,以展示恢複狀態會導致產生器再次產生同樣的值。

No state.dat, seeding0.134 0.847 0.764After saving state:0.255 0.495 0.449[Finished in 0.1s]Found state.dat, initializing random module0.255 0.495 0.449After saving state:0.652 0.789 0.094[Finished in 0.1s]Found state.dat, initializing random module0.652 0.789 0.094After saving state:0.028 0.836 0.433[Finished in 0.1s]
隨機整數

random將產生浮點數。可以把結果轉換為整數,不過直接使用randint產生整數會更方便。

import randomprint '[1, 100]:',for i in xrange(3):    print random.randint(1, 100),print '\n[-5, 5]:',for i in xrange(3):    print random.randint(-5, 5),print

randint的參數是值的閉區間的兩端,這些數可以是正數或負數,不過第一個值要小於第二個值.

[1, 100]: 35 39 28 [-5, 5]: -3 4 4[Finished in 0.1s]

randrange是從區間選擇值的一種更一般的形式。

import randomfor i in xrange(3):    print random.randrange(0, 101, 5),print

除了開始值(start)和結束值(stop), randrange還支援一個步長 step 參數,所以它完全等價於從range(start,stop,step)選擇一個隨機值。不過randrange更高效,因為它並沒有真正構造區間。

15 25 85[Finished in 0.1s]
選擇隨機元素

隨機數產生器有一種常見用法,即從一個枚舉值序列中選擇元素,即使這些值並不是數字。random包括一個choice函數,可以在一個序列中隨機播放。下面這個例子類比拋硬幣10000 次,來統計多少次面朝上,多少次面朝下,

import randomimport itertoolsoutcomes = { 'heads':0,             'tails':0,             }sides = outcomes.keys()for i in range(10000):    outcomes[ random.choice(sides) ] += 1print 'Heads:', outcomes['heads']print 'Tails:', outcomes['tails']

由於只允許兩個結果,所以不必使用數字然後再進行轉換,這裡對choice使用了單詞 “heads”(表示面朝上)和“tails”(表示面朝下)。結果以表格形式儲存在一個字典中,使用結果名作為鍵。

Heads: 5042Tails: 4958[Finished in 0.1s]
排列

要類比一個撲克牌遊戲,需要把一副牌混起來,然後向玩家發牌,同一張牌不能多次使用。使用choice可能導致同一張牌被發出兩次,所以可以用shuffle()來洗牌,然後在發各張牌時刪除所發的牌。

import randomimport itertoolsFACE_CARDS = ('J', 'Q', 'K', 'A')SUITS = ('H', 'D', 'C', 'S')def new_deck():    return list(itertools.product(            itertools.chain(xrange(2, 11), FACE_CARDS),            SUITS,            ))def show_deck(deck):    p_deck = deck[:]    while p_deck:        row = p_deck[:13]        p_deck = p_deck[13:]        for j in row:            print '%2s%s' % j,        print# Make a new deck, with the cards in orderdeck = new_deck()print 'Initial deck:'show_deck(deck)# Shuffle the deck to randomize the orderrandom.shuffle(deck)print '\nShuffled deck:'show_deck(deck)# Deal 4 hands of 5 cards eachhands = [ [], [], [], [] ]for i in xrange(5):    for h in hands:        h.append(deck.pop())# Show the handsprint '\nHands:'for n, h in enumerate(hands):    print '%d:' % (n+1),    for c in h:        print '%2s%s' % c,    print    # Show the remaining deckprint '\nRemaining deck:'show_deck(deck)

這些撲克牌表示為元組,由面值和一個表示花色的字母組成。要建立已發出“一手牌”,可以一次向4個列表分別增加一張牌,然後從這副牌中將其刪除,使這些牌不會再次發出。

Initial deck: 2H  2D  2C  2S  3H  3D  3C  3S  4H  4D  4C  4S  5H 5D  5C  5S  6H  6D  6C  6S  7H  7D  7C  7S  8H  8D 8C  8S  9H  9D  9C  9S 10H 10D 10C 10S  JH  JD  JC JS  QH  QD  QC  QS  KH  KD  KC  KS  AH  AD  AC  ASShuffled deck: 3C  8S  QC  5D  2C  9H  QH  KC  AS  4D  5H 10D  QS 3S  5S  JS  AD  QD  5C  KS  8H  4S  3H  7S 10C  6D 3D  2S  7D  4C  2H  9S  2D  6S  4H  6C  AC  JD  8D10H  KH  KD  JC  6H  9C  JH  7C 10S  8C  AH  9D  7HHands:1:  7H 10S  6H 10H  6C2:  9D  7C  JC  8D  4H3:  AH  JH  KD  JD  6S4:  8C  9C  KH  AC  2DRemaining deck: 3C  8S  QC  5D  2C  9H  QH  KC  AS  4D  5H 10D  QS 3S  5S  JS  AD  QD  5C  KS  8H  4S  3H  7S 10C  6D 3D  2S  7D  4C  2H  9S[Finished in 0.1s]
採樣

很多類比需要從大量輸入值中得到隨機樣本sample()函數可以產生無重複值的樣本,且不會修改輸入序列。下面的例子會列印系統字典中單詞的一個隨機樣本。

import randomwith open('words.txt', 'rt') as f:    words = f.readlines()words = [ w.rstrip() for w in words ]for w in random.sample(words, 5):    print w

產生結果集的演算法會考慮輪入的規模和所請求的樣本,從而儘可能髙效地產生結果。

docibilityIturaeanyoudendriftsporidiumpansylike[Finished in 0.1s]Ituraeanpansylikejigamareedocibilityreadingdom[Finished in 0.1s]
多個並發產生器

除了模組層級函數,random還包括一個Random類來管理多個隨機數產生器的內部狀態。之前介紹的所有函數都可以作為Random執行個體的方法得到,而且各個執行個體可以單獨初始化和使用,而不會與其他執行個體返回的值相互幹擾。

import randomimport timeprint 'Default initializiation:\n'r1 = random.Random()r2 = random.Random()for i in xrange(3):    print '%04.3f  %04.3f' % (r1.random(), r2.random())print '\nSame seed:\n'seed = time.time()r1 = random.Random(seed)r2 = random.Random(seed)for i in xrange(3):    print '%04.3f  %04.3f' % (r1.random(), r2.random())

如杲系統上設定了很好的內建隨機值種子,不同執行個體會有惟一的初始狀態。不過,如果沒有一個好的平台隨機值產生器,不同執行個體往往會用目前時間作為種子,因此會產生相同的值。

Default initializiation:0.189  0.3070.466  0.3280.020  0.757Same seed:0.510  0.5100.981  0.9810.679  0.679[Finished in 0.1s]

為了確保產生器從隨機周期的不同部分產生值,可以使用jumpahead調整其中一個產生器的初始狀態。

Default initializiation:0.189  0.3070.466  0.3280.020  0.757Same seed:0.510  0.5100.981  0.9810.679  0.679[Finished in 0.1s]
SystemRandom

有些作業系統提供了一個隨機數產生器,可以訪問更多能夠引入產生器的資訊源。 random通過SystemRandom類提供了這個特性,這個類與Random的API相同,不過使用os.urandom()產生值,這構成了所有其他演算法的基礎。

import randomimport timeprint 'Default initializiation:\n'r1 = random.SystemRandom()r2 = random.SystemRandom()for i in xrange(3):    print '%04.3f  %04.3f' % (r1.random(), r2.random())print '\nSame seed:\n'seed = time.time()r1 = random.SystemRandom(seed)r2 = random.SystemRandom(seed)for i in xrange(3):    print '%04.3f  %04.3f' % (r1.random(), r2.random())

SystemRandom產生的序列是不可再生的,因為其隨機性來自系統,而不是來自軟體狀態 (實際上,seed()和setstate()根本不起作用).

Default initializiation:0.945  0.2010.767  0.2950.984  0.383Same seed:0.584  0.3240.598  0.6240.400  0.310[Finished in 0.1s]
非均勻分布

random產生的值為均勻分布,這對於很多用途來說非常有用,不過,另外一些分布可以更準確地對特定情況建模。random模組還包含一些函數來產生這樣一些分布的值。這裡將列出 這些分布,但是並不打算詳細介紹,因為它們往往只在特定條件下使用,而且需要更複雜的例 子來說明。

常態分佈

常態分佈(normal distribution)常用於非均勻的連續值,如梯度、髙度、重設等等.正態 分布產生的曲線有一個獨特形狀,所以被暱稱為“鐘形曲線”。random包含兩個函數可以產生 常態分佈的值,分別是normalvariate和稍快一些的gauss。(常態分佈也稱為髙斯分布。) 還有一個相關的函數lognormvariate,它可以產生對數呈常態分佈的偽隨機值。對數常態分佈適用於多個不互動隨機變數的積。

近似分布

三角分布用於小樣本的近似分布。三角分布的“曲線”中,低點在已知的最小和最大值,在模式值處有一個髙點,這要根據“最接近”的結果(由triangularO的模式參數反映)來估計。

指數分布

expovariate可以產生一個指數分布,這對於類比到達或間隔時間值用於齊次泊松過程會很有用,如放射衰變速度或到達Web伺服器的請求。很多可觀察的現象都適用帕累托分布或冪律分布,這個分布因Chris Anderson的“長尾效應”而普及。paretovariatc()函數對於槙擬資源分派很有用(人的財宮、音樂家的需求、對部落格的關注,等等)。

角分布

米塞斯分布或圓常態分佈(由vonmisesvariate產生)用於計算周期值的機率,如角度、 日曆日期和時間。

大小分布

betavariate產生Beta分布的值,常用於貝葉斯統計和應用,如任務期間建模。 gammavariate()產生的伽瑪分布用於對事物的大小建模,如等待時間、雨量和計算錯誤。 weibullvariate計算的韋伯分布用於故障分析、工業工程和天氣預報。它描述了粒子或其 他離散對象的大小分布。

Python STL random

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.