Fisher–Yates shuffle 洗牌算法(zz)
1,缘起
最近工作上遇到一个问题,即将一组数据,比如[A,B,C,D,E]其中的两个B,E按随机排列,其他的仍在原来的位置:
原始数组:[A,B,C,D,E]
随机字母:[B,D]
可能结果:[A,B,C,D,E],[A,D,C,B,E]
在解决这个问题的过程中,需要解决的一个问题是,怎么样让一个数组随机排序?上网一查,这也是计算机科学基础问题,也称之为洗牌算法(Shuffle Algorithm)。
2,问题及解决
2.1,问题
很简单:给定一个数组,将其中的元素随机排列。比如给定数组arry=>[1,2,3,4,5]。有A5-5种结果即5!=120种结果
2.2,解决
也很简单,如果用白话来说就是:
a,选中第1个元素,将其与n个元素中的任意一个交换(包括第1个元素自己)。这时排序后的第1个元素已经确定。
b,选中第2个元素,将其与n-1个元素中作任意一个交换(包括第2个元素自己)。
c,重复上面步骤,直到剩1个元素为止。
3.3,代码
public static void Shuffle<T>(this IList<T> list)
{
Random rng = new Random();
int n = list.Count;
while (n > 1)
{
n--;
int k = rng.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
3.4,其它
该算法复杂度为O(n),且无偏差,各个元素随机概率相等。确实是一个好算法:)。
在Wiki上,还有一些该算法的变种,但还是上面讲的那种比较好用,最初的Fisher–Yates算法并不好用,复杂度为O(n^2)。
Fisher–Yates shuffle 洗牌算法(zz)的更多相关文章
- Fisher–Yates shuffle 洗牌算法
Fisher-Yates shuffle 是一种生成有限序列的随机排列的算法--简单地说,该算法可以对序列进行混排.本人能力有限,且懒.不会扒论文去研究该算法在数学上的证明,只能抄袭网上的博客总结一遍 ...
- Fisher–Yates shuffle 洗牌(shuffle)算法
今天在敲undersore的源码,数组里面有一个shuffle,把数组随机打乱. _.shuffle = function(obj) { var set = isArrayLike(obj) ? ob ...
- random array & shuffle 洗牌算法 / 随机算法
random array & shuffle shuffle 洗牌算法 / 随机算法 https://en.wikipedia.org/wiki/Fisher–Yates_shuffle ES ...
- 由乱序播放说开了去-数组的打乱算法Fisher–Yates Shuffle
之前用HTML5的Audio API写了个音乐频谱效果,再之后又加了个播放列表就成了个简单的播放器,其中弄了个功能是'Shuffle'也就是一般播放器都有的列表打乱功能,或者理解为随机播放. 但我觉得 ...
- 洗牌算法shuffle
对这个问题的研究始于一次在群里看到朋友发的洗牌面试题.当时也不知道具体的解法如何,于是随口回了一句:每次从剩下的数字中随机一个.过后找相关资料了解了下,洗牌算法大致有3种,按发明时间先后顺序如下: 一 ...
- 洗牌算法及 random 中 shuffle 方法和 sample 方法浅析
对于算法书买了一本又一本却没一本读完超过 10%,Leetcode 刷题从来没坚持超过 3 天的我来说,算法能力真的是渣渣.但是,今天决定写一篇跟算法有关的文章.起因是读了吴师兄的文章<扫雷与算 ...
- 随机洗牌算法Knuth Shuffle和错排公式
Knuth随机洗牌算法:譬如现在有54张牌,如何洗牌才能保证随机性.可以这么考虑,从最末尾一张牌开始洗,对于每一张牌,编号在该牌前面的牌中任意一张选一张和当前牌进行交换,直至洗到第一张牌为止.参考代码 ...
- js 随机数 洗牌算法
function shuffle(arr){ var len = arr.length; for(var i = 0;i<len -1;i++) { var idx = Math.floor(M ...
- 洗牌算法Fisher_Yates原理
1.算法 http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle 简单的原理如下图所示: 2.原理 总结下,洗牌算法Fisher_Yates ...
随机推荐
- Docker下的Spring Cloud三部曲之一:极速体验
版权声明:欢迎转载,请注明出处,谢谢. http://blog.csdn.net/boling_cavalry/article/details/79177930 目录(?)[+] 从本章开始, ...
- python+正态分布+蒙特卡洛预测男女身高概率!
sklearn实战-乳腺癌细胞数据挖掘 https://study.163.com/course/introduction.htm?courseId=1005269003&utm_campai ...
- Java基础-SSM之Spring的POJO(Plain Old Java Object)实现AOP
Java基础-SSM之Spring的POJO(Plain Old Java Object)实现AOP 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 上次我分享过Spring传统的A ...
- the error about “no such file or directory”
CHENYILONG Blog the error about "no such file or directory" when you get the question like ...
- js基础知识:闭包,事件处理,原型
闭包:其实就是js代码在执行的时候会创建变量对象的一个作用域链,标识符解析的时候会沿着作用域链一级一级的网上搜索,最后到达全局变量停止.所以某个函数可以访问外层的局部变量和全局变量,但是访问不了里层的 ...
- html中的body和head有什么区别??
我的html文件如下: <html> <title>这是我的测试</title> <head> my test </head> <bo ...
- 运算符,比如+, -, >, <, 以及下标引用[start:end]等等,从根本上都是定义在类内部的方法。
python解释器在碰到+号运算符时,会调用加号前面的对象的__add__方法 class a: def __add__(self,b): print "ghh" aa=a() a ...
- [Alg::DP] Square Subsequence
题目如下: #include <iostream> #include <string> #include <vector> using namespace std; ...
- j2ee组件简介
- docker之容器访问和网络连接(三)
前言 当一台服务器上部署了多个应用容器,它们直接可能需要相互通信,比如web应用容器需要访问mysql数据库容器. 主机访问容器 通过映射端口的形式我们可以在外部访问容器内的服务 # 将主机的127. ...