【算法】洗牌算法Fisher–Yates shuffle

【算法】洗牌算法Fisher–Yates shuffle

C#語言一般都是調用隨機函數Random.Next函數,在一個範圍內隨機出一個數字。但是當我們需要將n個數據隨機選擇k個數。怎麼辦呢?

方案一:隨機出一個數,然後從剩下的數裏面接着隨機。

方案二:每次都從n個數據裏面隨機出一個數,遇到重複的,放回去。接着隨機,直到隨機出k個數。

我們的目的是不管用哪個方案,我們都需要保證選出的數要是等概率的。

方案一:取第1個數是1/n,第二個數是1/(n-1)…1

方案二:最壞的情況下我們從100個裏面隨機出99個,越到後面隨機出來的重複率越高。

Fisher–Yates shuffle

Fisher–Yates shuffle算法是高效和等概率的一個洗牌算法。其核心思想是從1到n之間隨機出一個數和最後一個數(n)交換,然後從1到n-1之間隨機出一個數和倒數第二個數(n-1)交換…假設我們有5個數0,1,2,3,4

0,1,2,3,4

1.從[0,4]這5個位置中(包含0和4)隨機出一個數(比如是3)和4號交換。

0,1,2,43

第4號位置放3的概率就是1/5

2.從[0,3]這4個位置中(包含0和3)隨機出一個數(比如是0)和3號交換。

4,1,2,0,3

第3號位置放0的概率就是(4/5)*(1/4)=1/5

3.從[0,2]這3個位置中(包含0和2)隨機出一個數(比如是0)和2號交換。

2,1,4,0,3

第2號位置放4的概率就是(4/5)x(3/4)x(1/3)=1/5

4.從[0,1]這2個位置中(包含0和1)隨機出一個數(比如是0)和1號交換。

12,4,0,3

第1號位置放2的概率就是(4/5)x(3/4)x(2/3)x(1/2)=1/5

5.從[0,0]這1個位置中(包含0和0)隨機出一個數(比如是0)和0號交換。

1,2,4,0,3

第0號位置放1的概率就是(4/5)x(3/4)x(2/3)x(1/2)=1/5

其實第5步驟就是不用交換了。

那麼我們再回到之前的問題,取出k個數。其實我們將這幾個數字洗完之後,即已經隨機打亂了。所以從裏面按照順序取出k個數即可。

如果本文對你有所幫助,歡迎讚賞~~~

歡迎關注微信公衆號:Unity遊戲開發筆記
在這裏插入圖片描述
QQ羣:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章