如何給撲克牌洗牌才能更顯公平性
- 📻前言
- 一、🎙?需求分析 - 洗牌問題
- 二、💿實作版本
- 1. 版本一:常規思維
- 2. 版本二:驗證公平性
- 3. 版本三:交換法則
- 三、📺在線Online
- 四、📹結束語
- 📸往期推薦
📻前言
平常在日常生活中,我們總會遇到公平性這個話題,比如,幾個人分獎品,怎么樣才能公平分配?又或者,年會來個抽獎轉盤,怎么樣才能讓它更公平呢?
那在下面這篇文章呢,我們將談論關于洗牌的公平性,一起來了解吧~
一、🎙?需求分析 - 洗牌問題
有時候我們在閑暇之余可能會打打斗地主之類的撲克游戲,但是這撲克要怎么去洗牌,才能不失公平性呢?

那么接下來,我們由淺入深的來講解一種實作效果,
二、💿實作版本
1. 版本一:常規思維
先附上代碼:
JS 代碼:
const cards = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
function shuffle(cards) {
return [...cards].sort(() => Math.random() > 0.5 ? -1 : 1);
}
console.log(shuffle(cards)); // [5, 4, 3, 2, 1, 9, 0, 6, 8, 7]
如果說要公平,那很多小伙伴剛開始想的應該是隨機打亂,但是其實 Math.random() 并不能真正起到真正的隨機,
它的隨機性跟原來的位置相關,它是隨機的去交換原來兩個數的位置,而這個位置是否會產生交換的不確定性也很大,所以它并沒辦法達到真正的公平,
2. 版本二:驗證公平性
先附上代碼:
JS 代碼:
const cards = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
function shuffle(cards) {
return [...cards].sort(() => Math.random() > 0.5 ? -1 : 1);
}
const result = Array(10).fill(0);
for(let i = 0; i < 1000000; i++) {
const c = shuffle(cards);
for(let j = 0; j < 10; j++) {
result[j] += c[j];
}
}
console.log(result);
依據版本一的例子,我們來看下它為什么不公平,先看下列印效果:

大家可以看到,如果這個演算法是公平的,那它從第一個數到最后一個數應該都是比較平均的,而在這個演算法中,越靠后的數,其數值會越大,所以這個隨機性明顯是有問題的,一般來說,如果用這個演算法的話,排在越后面的同學的中獎概率,會比排在前面的同學的中獎概率要小,
3. 版本三:交換法則
先附上代碼:
JS 代碼:
const cards = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
function shuffle(cards) {
const c = [...cards];
for(let i = c.length; i > 0; i--) {
const pIdx = Math.floor(Math.random() * i);
[c[pIdx], c[i - 1]] = [c[i - 1], c[pIdx]];
}
return c;
}
//驗證是否公平
const result = Array(10).fill(0);
for(let i = 0; i < 10000; i++) {
const c = shuffle(cards);
for(let j = 0; j < 10; j++) {
result[j] += c[j];
}
}
console.log(shuffle(cards));
console.log(result);
基于前面兩個版本的瑕疵,我們來實作一種公平的寫法,上面的這種演算法呢,其復雜度是 O(n) ,它的實作邏輯是,在整個有序陣列中,先隨機抽取任意一個數,把它放到最后的位置,之后再隨機抽取任意一個數,再把它換到最后一個位置進行交換,以此類推,具體思路如下圖所示:

下面來看控制臺列印效果:

大家可以看到,控制臺列印出來的數都是相對比較平均的,而不會前后差異特別大,所以,這個演算法是公平的,
三、📺在線Online
以上三個版本的在線地址:
- 版本一:常規思維
- 版本二:驗證公平性
- 版本三:交換法則
四、📹結束語
在上面的文章中,我們首先談論了平常常用的隨機洗牌法的不公平性,之后重新介紹了一種新的交換法則來實作洗牌的公平性,不知道大家對洗牌問題是否有了進一步了解呢?
如果您覺得這篇文章有幫助到您的的話不妨點贊支持一下喲~~😉
📸往期推薦
👉緊跟月影大佬的步伐,一起來學習如何寫好JS(上)
👉緊跟月影大佬的步伐,一起來學習如何寫好JS(下)
👉每天都在紅綠燈前面梭行,不如自己來實作個紅綠燈?
👉冪等問題 vs 如何判斷是否是4的冪
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/306031.html
標籤:其他
