關於python shuffle函式隨機性的測試

2021-10-05 17:49:20 字數 3592 閱讀 8804

牌堆=

[i for i in

range

(160)]

棄牌堆=

for i in

range

(len

(牌堆)):

)import time

import numpy as np

def 洗牌(棄牌堆)

:global 牌堆

import random

#random.seed(time.time())

random.shuffle(棄牌堆)

#棄牌堆 = np.random.permutation(棄牌堆)

return 棄牌堆

重合次數=

for i in

range

(len

(牌堆)):

0)for u in

range

(100000):

new = 洗牌(棄牌堆)

for i in

range

(len

(牌堆)):

if 牌堆[i]

==new[i]

: 重合次數[i]+=1

print

(重合次數)

目前python主要使用的打亂列表(陣列)的方法主要是這兩種,

random.shuffle()

numpy.random.permutation()

經過上面**的測試,分別有以下結果

#100000次呼叫shuffle方法

[667, 691, 627, 616, 612, 630, 646, 615, 630, 633, 611, 606, 677, 583, 647, 609, 633, 626, 628, 609, 603, 614, 598, 578, 608, 631, 604, 591, 616, 594, 631, 654, 630, 645, 606, 622, 678, 618, 609, 669, 633, 605, 627, 603, 621, 626, 646, 652, 670, 646, 669, 625, 573, 615, 639, 629, 617, 626, 625, 601, 649, 623, 618, 645, 657, 624, 676, 634, 598, 657, 642, 606, 642, 577, 602, 641, 642, 604, 607, 667, 594, 614, 639, 626, 671, 609, 597, 621, 610, 636, 613, 660, 604, 581, 622, 642, 634, 641, 641, 620, 649, 612, 575, 626, 619, 662, 591, 639, 602, 627, 642, 638, 611, 645, 622, 639, 680, 627, 665, 579, 595, 654, 598, 624, 618, 634, 611, 693, 650, 609, 635, 633, 587, 585, 644, 636, 663, 643, 620, 626, 651, 606, 610, 639, 640, 662, 567, 627, 602, 644, 585, 606, 670, 616, 653, 623, 606, 601, 590, 623]

#100000次呼叫permutation方法

[614, 636, 643, 638, 632, 586, 585, 628, 612, 589, 635, 643, 601, 634, 628, 597, 675, 589, 602, 653, 621, 613, 660, 602, 655, 553, 562, 579, 628, 630, 651, 646, 651, 580, 588, 630, 652, 636, 600, 629, 583, 579, 644, 650, 592, 615, 643, 617, 677, 631, 642, 628, 612, 628, 623, 620, 612, 603, 630, 655, 588, 610, 612, 635, 615, 638, 631, 636, 626, 681, 614, 626, 617, 638, 630, 650, 615, 609, 632, 574, 617, 585, 587, 601, 611, 613, 574, 618, 632, 632, 609, 608, 646, 609, 610, 626, 615, 629, 635, 655, 606, 616, 588, 639, 597, 605, 667, 612, 668, 618, 565, 610, 633, 617, 629, 643, 587, 577, 610, 606, 599, 627, 586, 602, 651, 624, 584, 627, 620, 608, 638, 614, 639, 630, 660, 627, 557, 641, 656, 621, 618, 650, 638, 659, 621, 661, 603, 646, 600, 604, 563, 607, 626, 582, 623, 627, 587, 672, 594, 638]

我本著學習的態度,查閱了shuffle方法的源**

核心的**就3行,其實就是非常經典的fisher–yates shuffle演算法的實現,fisher–yates shuffle演算法偽碼如下:

– to shuffle an array a of n elements (indices 0…n-1):

for i from n−1 downto 1 do

j ← random integer such that 0 ≤ j ≤ i

exchange a[j] and a[i]   

第一步 即從0到n-1個元素中隨機選擇乙個與第n-1個替換

第二步 從0到n-2個元素中隨機選擇乙個與第n-2個替換

第k步 從0到n-k個元素中隨機選擇乙個與第n-k個替換

我們先從第一步來看,

假設有4個元素

第1個元素被替換的概率是1/4

第2個元素被替換的概率是1/4

第3個元素被替換的概率是1/4

第4個元素被替換的概率是3/4

然後進行第二步,此時最後一位元素被固定,它對於每個元素都有1/4的概率

若第1個元素被替換:

[4,2,3,1]

第二次替換過程中

第1個元素被替換的概率是1/3

第2個元素被替換的概率是1/3

第3個元素被替換的概率是2/3

同理可知其他情況

所以第三位元素在第二次替換過程中,

對於第1個元素有1/4

*0+3

/4*1

/3=1

/4對於第2個元素有1/4

*0+3

/4*1

/3=1

/4對於第3個元素有1/4

*0+3

/4*1

/3=1

/4對於第4個元素有1/4

*1+3

/4*0

=1/4

易於理解 每個位置取到每個元素的概率都是均等的

最後還是要說一點

random.shuffle()和numpy.random.permutation()方法有乙個小區別要注意

permutation的返回值是numpy.ndarray型別,不要把它當做列表型別了

關於程式關於世界

首先,在學了1年多的軟體設計的基礎上,問下自己 程式是什麼?業務需求是什麼?程式有什麼用?什麼是演算法?什麼是資料庫?或許每個人的理解不同,會給出不同的答案。那麼自己的理解 程式是乙個讓計算機工作的流程,在程式寫好之後,計算機就會按照,程式設計師定義好流程在執行。其實很多時候,乙個程式的好壞,在於乙...

關於血液關於軟體

1 自然沉降法 將血袋垂直吊掛於4 2 冰箱內,使紅細胞自然下沉1 3d,或將血袋呈70 80 角立於冰箱,需用時,用一次性分漿器分出血漿,制得濃縮紅細胞。2 洗滌法 一般用生理鹽水反覆洗滌3 6次。經洗滌的紅細胞,除白細胞和血小板減少外,血漿蛋白也極少,紅細胞中殘存的血漿蛋白含量約為原總蛋白的1 ...

關於冷漠,關於愛情

我不知道為什麼今天又莫名其妙開始思考愛情這件事,隨之就解決了我一直無法面對冷漠這件事 被冷漠是我始終無法消化的一件事,每當遇見冷漠時,我總會覺得就像一團火把自己燒得面目全非,但對方卻毫無傷害。但我突然懂了,遇到冷漠時,體面的離開即可 在乎你的人一定會在你離開後,找到你跟你解釋為什麼 連解釋都來不及,...