发表于: 2017-04-22 20:21:27

2 1401


洗牌算法具体指的是什么

一、背景介绍

洗牌算法(Shuffling Algorithm),顾名思义,它的产生是用来解决类似洗牌这种场景的问题的,目的是产生一串等概率的随机列,使得很难去预测牌的顺序。
现在的各种牌类游戏都有自己的洗牌算法,为了保证游戏的趣味性,各自的实现中都有自己考虑的因素添加在其中。
1999年,一个很流行的在线扑克平台的开发者开发的洗牌软件,带有很微小但很致命的漏洞,导致了灾难性的结果。
黑客只要知道手中的两张牌和3张公用牌,就可以猜出转牌和河牌时会来什么牌,以及其他玩家的牌。
洗牌算法的应用也很广,比如三国杀游戏、斗地主游戏等等。讲一个最常见的场景,就是播放器的随机播放。有些播放器的随机播放,是每次产生一个随机数来选择播放的歌曲,这样就有可能还没有听完所有的歌前,又听到已经听过的歌。
另一种就是利用洗牌算法,把待播放的歌曲列表shuffle。如何判断使用的是哪一种方案呢? 很简单,如果点上一首还能回去,则利用的是洗牌算法,如果点上一首又是另外一首歌,则说明使用的是随机产生方法。

二、知识剖析

Fisher–Yates Shuffle

其算法思想就是 从原始数组中随机抽取一个新的元素到新数组中。
从还没处理的数组中,产生一个[0, n]之间的随机数 random。
从剩下的n个元素中把第 random 个元素取出到新数组中。
删除原数组第random个元素。
重复第 2 3 步直到所有元素取完。
最终返回一个新的打乱的数组。

Knuth-Durstenfeld Shuffle

每次从未处理的数组中随机取一个元素,然后把该元素放到数组的尾部,即数组的尾部放的就是已经处理过的元素,这是一种原地打乱的算法,每个元素随机概率也相等,时间复杂度从 Fisher 算法的 O(n2)提升到了 O(n)。
选取数组(长度n)中最后一个元素(arr[length-1]),将其与n个元素中的任意一个交换,此时最后一个元素已经确定。
选取倒数第二个元素(arr[length-2]),将其与n-1个元素中的任意一个交换。
重复第 1 2 步,直到剩下1个元素为止。

Inside-Out Algorithm

Inside-Out Algorithm 算法的基本思想是设一游标i从前向后扫描原始数据的拷贝,在[0, i]之间随机一个下标j,然后用位置j的元素替换掉位置i的数字,再用原始数据位置i的元素替换掉拷贝数据位置j的元素。其作用相当于在拷贝数据中交换i与j位置处的值。

三、常见问题

Fisher–Yates Shuffle是如何实现的?

四、解决方案

Fisher–Yates Shuffle的JS实现

shuffle 函数挂载在 Array 对象的原型之下,便于数组直接调用该函数。在 shuffle 函数内部,this 引用的就是调用该 shuffle 的数组。
用一个新的变量引用 this,也就是调用 shuffle 函数的数组。接下来的for循环用于遍历所有数组内的所有元素,并进行随机交换。
注意,遍历顺序是从后往前进行的,也就是说从 input.length-1 位置的元素开始,直到遍历到数组中的第一个元素。遍历过程中的位置由变量 i 指定。
接下来,使用了两行代码在指定范围内挑选一个随机元素。 变量randomIndex存储了一个随机数,该随机数可以用作数组的索引,进而提取一个随机元素。注意,该随机数的最大值并不是数组的长度,而是变量i的值。
确定了随机元素的索引之后,用新的变量保存该元素的值,然后交换选中元素和随机元素的值。

五、编码实战

Array.prototype.shuffle = function() {
var input = this;
for (var i = input.length - 1; i >= 0; i–) {
var randomIndex = Math.floor(Math.random() * (i + 1));//获取小于this.length的随机整数
var itemAtIndex = input[randomIndex];
input[randomIndex] = input[i];
input[i] = itemAtIndex;//input[randomIndex]和input[i]交换值
}
return input;
}

六、拓展思考

怎么保证这个算法得到的数组是完全随机的(即等概)?

使用程序得到的一般是伪随机数。

笔者目前了解到最优秀的是梅森旋转算法,其在低于623次元的空间以内不存在线性回归,但仍然是一个伪随机算法。

七、参考文献

参考一:洗牌算法怎样才够乱
参考二: 洗牌算法shuffle - caochao88
参考三:当随机不够随机:一个在线扑克游戏的教训
参考四: 随机问题之–洗牌算法

八、更多讨论

还有没有更简单的洗牌算法

使用JS自带函数sort()实现洗牌。

%u6D17%u724C%u7B97%u6CD5%u5177%u4F53%u6307%u7684%u662F%u4EC0%u4E48%0A%3D%3D%3D%3D%3D%3D%3D%3D%3D%0A%23%23%u4E00%u3001%u80CC%u666F%u4ECB%u7ECD%0A%u6D17%u724C%u7B97%u6CD5%28Shuffling%20Algorithm%29%uFF0C%u987E%u540D%u601D%u4E49%uFF0C%u5B83%u7684%u4EA7%u751F%u662F%u7528%u6765%u89E3%u51B3%u7C7B%u4F3C%u6D17%u724C%u8FD9%u79CD%u573A%u666F%u7684%u95EE%u9898%u7684%uFF0C%u76EE%u7684%u662F%u4EA7%u751F%u4E00%u4E32%u7B49%u6982%u7387%u7684%u968F%u673A%u5217%uFF0C%u4F7F%u5F97%u5F88%u96BE%u53BB%u9884%u6D4B%u724C%u7684%u987A%u5E8F%u3002%0A%20%u73B0%u5728%u7684%u5404%u79CD%u724C%u7C7B%u6E38%u620F%u90FD%u6709%u81EA%u5DF1%u7684%u6D17%u724C%u7B97%u6CD5%uFF0C%u4E3A%u4E86%u4FDD%u8BC1%u6E38%u620F%u7684%u8DA3%u5473%u6027%uFF0C%u5404%u81EA%u7684%u5B9E%u73B0%u4E2D%u90FD%u6709%u81EA%u5DF1%u8003%u8651%u7684%u56E0%u7D20%u6DFB%u52A0%u5728%u5176%u4E2D%u3002%0A%201999%u5E74%uFF0C%u4E00%u4E2A%u5F88%u6D41%u884C%u7684%u5728%u7EBF%u6251%u514B%u5E73%u53F0%u7684%u5F00%u53D1%u8005%u5F00%u53D1%u7684%u6D17%u724C%u8F6F%u4EF6%uFF0C%u5E26%u6709%u5F88%u5FAE%u5C0F%u4F46%u5F88%u81F4%u547D%u7684%u6F0F%u6D1E%uFF0C%u5BFC%u81F4%u4E86%u707E%u96BE%u6027%u7684%u7ED3%u679C%u3002%0A%u9ED1%u5BA2%u53EA%u8981%u77E5%u9053%u624B%u4E2D%u7684%u4E24%u5F20%u724C%u548C3%u5F20%u516C%u7528%u724C%uFF0C%u5C31%u53EF%u4EE5%u731C%u51FA%u8F6C%u724C%u548C%u6CB3%u724C%u65F6%u4F1A%u6765%u4EC0%u4E48%u724C%uFF0C%u4EE5%u53CA%u5176%u4ED6%u73A9%u5BB6%u7684%u724C%u3002%0A%20%u6D17%u724C%u7B97%u6CD5%u7684%u5E94%u7528%u4E5F%u5F88%u5E7F%uFF0C%u6BD4%u5982%u4E09%u56FD%u6740%u6E38%u620F%u3001%u6597%u5730%u4E3B%u6E38%u620F%u7B49%u7B49%u3002%u8BB2%u4E00%u4E2A%u6700%u5E38%u89C1%u7684%u573A%u666F%uFF0C%u5C31%u662F%u64AD%u653E%u5668%u7684%u968F%u673A%u64AD%u653E%u3002%u6709%u4E9B%u64AD%u653E%u5668%u7684%u968F%u673A%u64AD%u653E%uFF0C%u662F%u6BCF%u6B21%u4EA7%u751F%u4E00%u4E2A%u968F%u673A%u6570%u6765%u9009%u62E9%u64AD%u653E%u7684%u6B4C%u66F2%uFF0C%u8FD9%u6837%u5C31%u6709%u53EF%u80FD%u8FD8%u6CA1%u6709%u542C%u5B8C%u6240%u6709%u7684%u6B4C%u524D%uFF0C%u53C8%u542C%u5230%u5DF2%u7ECF%u542C%u8FC7%u7684%u6B4C%u3002%0A%u53E6%u4E00%u79CD%u5C31%u662F%u5229%u7528%u6D17%u724C%u7B97%u6CD5%uFF0C%u628A%u5F85%u64AD%u653E%u7684%u6B4C%u66F2%u5217%u8868shuffle%u3002%u5982%u4F55%u5224%u65AD%u4F7F%u7528%u7684%u662F%u54EA%u4E00%u79CD%u65B9%u6848%u5462%uFF1F%20%u5F88%u7B80%u5355%uFF0C%u5982%u679C%u70B9%u4E0A%u4E00%u9996%u8FD8%u80FD%u56DE%u53BB%uFF0C%u5219%u5229%u7528%u7684%u662F%u6D17%u724C%u7B97%u6CD5%uFF0C%u5982%u679C%u70B9%u4E0A%u4E00%u9996%u53C8%u662F%u53E6%u5916%u4E00%u9996%u6B4C%uFF0C%u5219%u8BF4%u660E%u4F7F%u7528%u7684%u662F%u968F%u673A%u4EA7%u751F%u65B9%u6CD5%u3002%0A%23%23%u4E8C%u3001%u77E5%u8BC6%u5256%u6790%0A%23%23%23Fisher%u2013Yates%20Shuffle%0A%u5176%u7B97%u6CD5%u601D%u60F3%u5C31%u662F%20%u4ECE%u539F%u59CB%u6570%u7EC4%u4E2D%u968F%u673A%u62BD%u53D6%u4E00%u4E2A%u65B0%u7684%u5143%u7D20%u5230%u65B0%u6570%u7EC4%u4E2D%u3002%0A%u4ECE%u8FD8%u6CA1%u5904%u7406%u7684%u6570%u7EC4%u4E2D%uFF0C%u4EA7%u751F%u4E00%u4E2A%5B0%2C%20n%5D%u4E4B%u95F4%u7684%u968F%u673A%u6570%20random%u3002%0A%u4ECE%u5269%u4E0B%u7684n%u4E2A%u5143%u7D20%u4E2D%u628A%u7B2C%20random%20%u4E2A%u5143%u7D20%u53D6%u51FA%u5230%u65B0%u6570%u7EC4%u4E2D%u3002%0A%u5220%u9664%u539F%u6570%u7EC4%u7B2Crandom%u4E2A%u5143%u7D20%u3002%0A%u91CD%u590D%u7B2C%202%203%20%u6B65%u76F4%u5230%u6240%u6709%u5143%u7D20%u53D6%u5B8C%u3002%0A%u6700%u7EC8%u8FD4%u56DE%u4E00%u4E2A%u65B0%u7684%u6253%u4E71%u7684%u6570%u7EC4%u3002%0A%23%23%23Knuth-Durstenfeld%20Shuffle%0A%20%u6BCF%u6B21%u4ECE%u672A%u5904%u7406%u7684%u6570%u7EC4%u4E2D%u968F%u673A%u53D6%u4E00%u4E2A%u5143%u7D20%uFF0C%u7136%u540E%u628A%u8BE5%u5143%u7D20%u653E%u5230%u6570%u7EC4%u7684%u5C3E%u90E8%uFF0C%u5373%u6570%u7EC4%u7684%u5C3E%u90E8%u653E%u7684%u5C31%u662F%u5DF2%u7ECF%u5904%u7406%u8FC7%u7684%u5143%u7D20%uFF0C%u8FD9%u662F%u4E00%u79CD%u539F%u5730%u6253%u4E71%u7684%u7B97%u6CD5%uFF0C%u6BCF%u4E2A%u5143%u7D20%u968F%u673A%u6982%u7387%u4E5F%u76F8%u7B49%uFF0C%u65F6%u95F4%u590D%u6742%u5EA6%u4ECE%20Fisher%20%u7B97%u6CD5%u7684%20O%28n2%29%u63D0%u5347%u5230%u4E86%20O%28n%29%u3002%0A%u9009%u53D6%u6570%u7EC4%28%u957F%u5EA6n%29%u4E2D%u6700%u540E%u4E00%u4E2A%u5143%u7D20%28arr%5Blength-1%5D%29%uFF0C%u5C06%u5176%u4E0En%u4E2A%u5143%u7D20%u4E2D%u7684%u4EFB%u610F%u4E00%u4E2A%u4EA4%u6362%uFF0C%u6B64%u65F6%u6700%u540E%u4E00%u4E2A%u5143%u7D20%u5DF2%u7ECF%u786E%u5B9A%u3002%0A%u9009%u53D6%u5012%u6570%u7B2C%u4E8C%u4E2A%u5143%u7D20%28arr%5Blength-2%5D%29%uFF0C%u5C06%u5176%u4E0En-1%u4E2A%u5143%u7D20%u4E2D%u7684%u4EFB%u610F%u4E00%u4E2A%u4EA4%u6362%u3002%0A%u91CD%u590D%u7B2C%201%202%20%u6B65%uFF0C%u76F4%u5230%u5269%u4E0B1%u4E2A%u5143%u7D20%u4E3A%u6B62%u3002%0A%23%23%23Inside-Out%20Algorithm%20%0AInside-Out%20Algorithm%20%u7B97%u6CD5%u7684%u57FA%u672C%u601D%u60F3%u662F%u8BBE%u4E00%u6E38%u6807i%u4ECE%u524D%u5411%u540E%u626B%u63CF%u539F%u59CB%u6570%u636E%u7684%u62F7%u8D1D%uFF0C%u5728%5B0%2C%20i%5D%u4E4B%u95F4%u968F%u673A%u4E00%u4E2A%u4E0B%u6807j%uFF0C%u7136%u540E%u7528%u4F4D%u7F6Ej%u7684%u5143%u7D20%u66FF%u6362%u6389%u4F4D%u7F6Ei%u7684%u6570%u5B57%uFF0C%u518D%u7528%u539F%u59CB%u6570%u636E%u4F4D%u7F6Ei%u7684%u5143%u7D20%u66FF%u6362%u6389%u62F7%u8D1D%u6570%u636E%u4F4D%u7F6Ej%u7684%u5143%u7D20%u3002%u5176%u4F5C%u7528%u76F8%u5F53%u4E8E%u5728%u62F7%u8D1D%u6570%u636E%u4E2D%u4EA4%u6362i%u4E0Ej%u4F4D%u7F6E%u5904%u7684%u503C%u3002%0A%23%23%u4E09%u3001%u5E38%u89C1%u95EE%u9898%0A%23%23%23Fisher%u2013Yates%20Shuffle%u662F%u5982%u4F55%u5B9E%u73B0%u7684%uFF1F%0A%23%23%u56DB%u3001%u89E3%u51B3%u65B9%u6848%0A%23%23%23Fisher%u2013Yates%20Shuffle%u7684JS%u5B9E%u73B0%0Ashuffle%20%u51FD%u6570%u6302%u8F7D%u5728%20Array%20%u5BF9%u8C61%u7684%u539F%u578B%u4E4B%u4E0B%uFF0C%u4FBF%u4E8E%u6570%u7EC4%u76F4%u63A5%u8C03%u7528%u8BE5%u51FD%u6570%u3002%u5728%20shuffle%20%u51FD%u6570%u5185%u90E8%uFF0Cthis%20%u5F15%u7528%u7684%u5C31%u662F%u8C03%u7528%u8BE5%20shuffle%20%u7684%u6570%u7EC4%u3002%0A%u7528%u4E00%u4E2A%u65B0%u7684%u53D8%u91CF%u5F15%u7528%20this%uFF0C%u4E5F%u5C31%u662F%u8C03%u7528%20shuffle%20%u51FD%u6570%u7684%u6570%u7EC4%u3002%u63A5%u4E0B%u6765%u7684for%u5FAA%u73AF%u7528%u4E8E%u904D%u5386%u6240%u6709%u6570%u7EC4%u5185%u7684%u6240%u6709%u5143%u7D20%uFF0C%u5E76%u8FDB%u884C%u968F%u673A%u4EA4%u6362%u3002%0A%u6CE8%u610F%uFF0C%u904D%u5386%u987A%u5E8F%u662F%u4ECE%u540E%u5F80%u524D%u8FDB%u884C%u7684%uFF0C%u4E5F%u5C31%u662F%u8BF4%u4ECE%20input.length-1%20%u4F4D%u7F6E%u7684%u5143%u7D20%u5F00%u59CB%uFF0C%u76F4%u5230%u904D%u5386%u5230%u6570%u7EC4%u4E2D%u7684%u7B2C%u4E00%u4E2A%u5143%u7D20%u3002%u904D%u5386%u8FC7%u7A0B%u4E2D%u7684%u4F4D%u7F6E%u7531%u53D8%u91CF%20i%20%u6307%u5B9A%u3002%0A%u63A5%u4E0B%u6765%uFF0C%u4F7F%u7528%u4E86%u4E24%u884C%u4EE3%u7801%u5728%u6307%u5B9A%u8303%u56F4%u5185%u6311%u9009%u4E00%u4E2A%u968F%u673A%u5143%u7D20%u3002%20%u53D8%u91CFrandomIndex%u5B58%u50A8%u4E86%u4E00%u4E2A%u968F%u673A%u6570%uFF0C%u8BE5%u968F%u673A%u6570%u53EF%u4EE5%u7528%u4F5C%u6570%u7EC4%u7684%u7D22%u5F15%uFF0C%u8FDB%u800C%u63D0%u53D6%u4E00%u4E2A%u968F%u673A%u5143%u7D20%u3002%u6CE8%u610F%uFF0C%u8BE5%u968F%u673A%u6570%u7684%u6700%u5927%u503C%u5E76%u4E0D%u662F%u6570%u7EC4%u7684%u957F%u5EA6%uFF0C%u800C%u662F%u53D8%u91CFi%u7684%u503C%u3002%0A%u786E%u5B9A%u4E86%u968F%u673A%u5143%u7D20%u7684%u7D22%u5F15%u4E4B%u540E%uFF0C%u7528%u65B0%u7684%u53D8%u91CF%u4FDD%u5B58%u8BE5%u5143%u7D20%u7684%u503C%uFF0C%u7136%u540E%u4EA4%u6362%u9009%u4E2D%u5143%u7D20%u548C%u968F%u673A%u5143%u7D20%u7684%u503C%u3002%0A%23%23%u4E94%u3001%u7F16%u7801%u5B9E%u6218%0AArray.prototype.shuffle%20%3D%20function%28%29%20%7B%0A%20%20%20%20var%20input%20%3D%20this%3B%0A%20%20%20%20for%20%28var%20i%20%3D%20input.length%20-%201%3B%20i%20%3E%3D%200%3B%20i--%29%20%7B%0A%20%20%20%20%20%20var%20randomIndex%20%3D%20Math.floor%28Math.random%28%29%20*%20%28i%20+%201%29%29%3B//%u83B7%u53D6%u5C0F%u4E8Ethis.length%u7684%u968F%u673A%u6574%u6570%0A%20%20%20%20%20%20var%20itemAtIndex%20%3D%20input%5BrandomIndex%5D%3B%0A%20%20%20%20%20%20input%5BrandomIndex%5D%20%3D%20input%5Bi%5D%3B%0A%20%20%20%20%20%20input%5Bi%5D%20%3D%20itemAtIndex%3B//input%5BrandomIndex%5D%u548Cinput%5Bi%5D%u4EA4%u6362%u503C%0A%20%20%20%20%7D%0A%20%20%20%20return%20input%3B%0A%20%20%7D%0A%23%23%u516D%u3001%u62D3%u5C55%u601D%u8003%0A%23%23%23%u600E%u4E48%u4FDD%u8BC1%u8FD9%u4E2A%u7B97%u6CD5%u5F97%u5230%u7684%u6570%u7EC4%u662F%u5B8C%u5168%u968F%u673A%u7684%uFF08%u5373%u7B49%u6982%uFF09%uFF1F%0A%23%23%23%23%u4F7F%u7528%u7A0B%u5E8F%u5F97%u5230%u7684%u4E00%u822C%u662F%u4F2A%u968F%u673A%u6570%u3002%0A%u7B14%u8005%u76EE%u524D%u4E86%u89E3%u5230%u6700%u4F18%u79C0%u7684%u662F%u6885%u68EE%u65CB%u8F6C%u7B97%u6CD5%uFF0C%u5176%u5728%u4F4E%u4E8E623%u6B21%u5143%u7684%u7A7A%u95F4%u4EE5%u5185%u4E0D%u5B58%u5728%u7EBF%u6027%u56DE%u5F52%uFF0C%u4F46%u4ECD%u7136%u662F%u4E00%u4E2A%u4F2A%u968F%u673A%u7B97%u6CD5%u3002%0A%23%23%u4E03%u3001%u53C2%u8003%u6587%u732E%0A%u53C2%u8003%u4E00%uFF1A%5B%u6D17%u724C%u7B97%u6CD5%u600E%u6837%u624D%u591F%u4E71%5D%28https%3A//www.zhihu.com/question/23810169%29%0A%u53C2%u8003%u4E8C%uFF1A%5B%20%u6D17%u724C%u7B97%u6CD5shuffle%20-%20caochao88%20%5D%28http%3A//www.tuicool.com/articles/qIjqQzb%29%0A%u53C2%u8003%u4E09%uFF1A%5B%u5F53%u968F%u673A%u4E0D%u591F%u968F%u673A%uFF1A%u4E00%u4E2A%u5728%u7EBF%u6251%u514B%u6E38%u620F%u7684%u6559%u8BAD%5D%28http%3A//blog.jobbole.com/64897/%29%0A%u53C2%u8003%u56DB%3A%20%5B%u968F%u673A%u95EE%u9898%u4E4B--%u6D17%u724C%u7B97%u6CD5%5D%28http%3A//www.cnblogs.com/jkisjk/archive/2012/04/23/javascript_shuffle.html%29%0A%23%23%u516B%u3001%u66F4%u591A%u8BA8%u8BBA%0A%23%23%23%u8FD8%u6709%u6CA1%u6709%u66F4%u7B80%u5355%u7684%u6D17%u724C%u7B97%u6CD5%0A%u4F7F%u7528JS%u81EA%u5E26%u51FD%u6570sort%28%29%u5B9E%u73B0%u6D17%u724C%u3002%0A%20



返回列表 返回列表
评论

    分享到