【青训营】- 如何给扑克洗牌才能更公平?

简介: 平常在日常生活中,我们总会遇到公平性这个话题。比如,几个人分奖品,怎么样才能公平分配?又或者,年会来个抽奖转盘,怎么样才能让它更公平呢?那在下面这篇文章呢,我们将谈论关于洗牌的公平性。一起来了解吧~

30.png📻前言


平常在日常生活中,我们总会遇到公平性这个话题。比如,几个人分奖品,怎么样才能公平分配?又或者,年会来个抽奖转盘,怎么样才能让它更公平呢?

那在下面这篇文章呢,我们将谈论关于洗牌的公平性。一起来了解吧~


一、🎙️需求分析 - 洗牌问题


有时候我们在闲暇之余可能会打打斗地主之类的扑克游戏,但是这扑克要怎么去洗牌,才能不失公平性呢?

31.png

那么接下来,我们由浅入深的来讲解一种实现效果。


二、💿实现版本


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);
复制代码

依据版本一的例子,我们来看下它为什么不公平。先看下打印效果:

1.png

大家可以看到,如果这个算法是公平的,那它从第一个数到最后一个数应该都是比较平均的,而在这个算法中,越靠后的数,其数值会越大,所以这个随机性明显是有问题的。一般来说,如果用这个算法的话,排在越后面的同学的中奖概率,会比排在前面的同学的中奖概率要


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) ,它的实现逻辑是,在整个有序数组中,先随机抽取任意一个数,把它放到最后的位置,之后再随机抽取任意一个数,再把它换到最后一个位置进行交换,以此类推。具体思路如下图所示:

2.png

下面来看控制台打印效果:

3.png

大家可以看到,控制台打印出来的数都是相对比较平均的,而不会前后差异特别大。所以,这个算法是公平的。


三、📺在线Online


以上三个版本的在线地址:


四、📹结束语


在上面的文章中,我们首先谈论了平常常用的随机洗牌法的不公平性,之后重新介绍了一种新的交换法则来实现洗牌的公平性。不知道大家对洗牌问题是否有了进一步了解呢?

如果您觉得这篇文章有帮助到您的的话不妨点赞支持一下哟~~😉


相关文章
|
决策智能
博弈论第十七集总结(“声誉和决斗 ”观后感)
博弈论第十七集总结(“声誉和决斗 ”观后感)
42 0
【每日一道智力题】之 赛马找最快
【每日一道智力题】之 赛马找最快
143 0
|
算法
小玩意 - 抢红包算法(公平版 & 手速版)
小玩意 - 抢红包算法(公平版 & 手速版)
237 0
小玩意 - 抢红包算法(公平版 & 手速版)
|
存储 算法
蛋蛋惨遭数组滑铁卢,面试官建议回村养猪。
蛋蛋惨遭数组滑铁卢,面试官建议回村养猪。
蛋蛋惨遭数组滑铁卢,面试官建议回村养猪。
|
Java C语言
2021-06-03一个人不是生来就要被打败的
2021-06-03一个人不是生来就要被打败的
2021-06-03一个人不是生来就要被打败的
|
人工智能 算法 大数据
让AI读懂视频广告有多难?这道算法题4000多人挑战,冠军赢走了10万美元现金
在今年的腾讯广告算法大赛中,腾讯广告给全球算法圈出了一道难题,冠军最高奖励 10 万美元,赛题还入选了顶会挑战赛。什么赛题有如此含金量?谁拿走了冠军大奖?昨天,决赛结果已经出炉……
185 0
让AI读懂视频广告有多难?这道算法题4000多人挑战,冠军赢走了10万美元现金
|
Java
线程的故事:我的3位母亲成就了优秀的我!(1)
线程的故事:我的3位母亲成就了优秀的我!(1)
96 0
读《股票大作手操盘术》— 利弗莫尔操作法则
《股票大作手操盘术》读书笔记; 股票大作手操盘术是利弗莫尔本人写的一本著作,利弗莫尔在股民中的知名度自然不必多言,其著作中的思想放在当代也很有意义,所以最近拜读了一下。
1850 0
|
物联网 区块链
2018 展望 | 区块链:第一个高(泡)峰(沫)后,要迈几道坎?
区块链就像个成长中的孩子:该夸的时候要夸,该喂的时候要喂。但该吃的苦头,该碰的壁,也一样少不了。
1357 0