原地址:洗牌算法

对这个问题的研究始于一次在群里看到朋友发的洗牌面试题。当时也不知道具体的解法如何,于是随口回了一句:每次从剩下的数字中随机一个。过后找相关资料了解了下,洗牌算法大致有3种,按发明时间先后顺序如下:

一、Fisher–Yates Shuffle

算法思想就是从原始数组中随机抽取一个新的数字到新数组中。算法英文描述如下:

  • Write down the numbers from 1 through N.
  • Pick a random number k between one and the number of unstruck numbers remaining (inclusive).
  • Counting from the low end, strike out the kth number not yet struck out, and write it down elsewhere.
  • Repeat from step 2 until all the numbers have been struck out.
  • The sequence of numbers written down in step 3 is now a random permutation of the original numbers.

python实现代码如下:

#Fisher–Yates Shuffle
'''1. 从还没处理的数组(假如还剩k个)中,随机产生一个[0, k]之间的数字p(假设数组从0开始);2. 从剩下的k个数中把第p个数取出;3. 重复步骤2和3直到数字全部取完;4. 从步骤3取出的数字序列便是一个打乱了的数列。
'''
import randomdef shuffle(lis):result = []while lis:p = random.randrange(0, len(lis))result.append(lis[p])lis.pop(p)return resultr = shuffle([1, 2, 2, 3, 3, 4, 5, 10])
print(r)

二、Knuth-Durstenfeld Shuffle

  Knuth 和Durstenfeld 在Fisher 等人的基础上对算法进行了改进。每次从未处理的数据中随机取出一个数字,然后把该数字放在数组的尾部,即数组尾部存放的是已经处理过的数字。这是一个原地打乱顺序的算法,算法时间复杂度也从Fisher算法的O(n2)提升到了O(n)。算法伪代码如下:

以下两种实现方式的差异仅仅在于遍历的方向而已。下面用python实现前一个:

#Knuth-Durstenfeld Shuffle
def shuffle(lis):for i in range(len(lis) - 1, 0, -1):p = random.randrange(0, i + 1)lis[i], lis[p] = lis[p], lis[i]return lisr = shuffle([1, 2, 2, 3, 3, 4, 5, 10])
print(r)

三、Inside-Out Algorithm

Knuth-Durstenfeld Shuffle 是一个in-place算法,原始数据被直接打乱,有些应用中可能需要保留原始数据,因此需要开辟一个新数组来存储打乱后的序列。Inside-Out Algorithm 算法的基本思想是设一游标i从前向后扫描原始数据的拷贝,在[0, i]之间随机一个下标j,然后用位置j的元素替换掉位置i的数字,再用原始数据位置i的元素替换掉拷贝数据位置j的元素。其作用相当于在拷贝数据中交换i与j位置处的值。伪代码如下:

python代码实现如下:

#Inside-Out Algorithm
def shuffle(lis):result = lis[:]for i in range(1, len(lis)):j = random.randrange(0, i)result[i] = result[j]result[j] = lis[i]return resultr = shuffle([1, 2, 2, 3, 3, 4, 5, 10])
print(r)

、后话

前面用python实现了三种洗牌算法,其实python random模块也有个shuffle方法,用法如下:

其内部实现正是使用Knuth-Durstenfeld Shuffle算法,不信您看代码:-):

参考:

http://en.wikipedia.org/wiki/Fisher-Yates_shuffle

python——洗牌算法相关推荐

  1. python实现洗牌算法_洗牌算法及 random 中 shuffle 方法和 sample 方法浅析

    对于算法书买了一本又一本却没一本读完超过 10%,Leetcode 刷题从来没坚持超过 3 天的我来说,算法能力真的是渣渣.但是,今天决定写一篇跟算法有关的文章.起因是读了吴师兄的文章 <扫雷与 ...

  2. 从洗牌算法谈起--Python的random.shuffle函数实现原理

    此文首发于我的个人博客:从洗牌算法谈起–random.shuffle实现原理 - zhang0peter的个人博客 昨天看知乎的时候看到了洗牌算法(Knuth shuffle, 最初版本叫Fisher ...

  3. python实现洗牌算法_如何高效而完美地洗牌?用Python做很简单

    Python不用学,看看你就懂:拿来就能用,用用你就会 无需安装编程软件,把代码拷贝到在线编辑器即可运行 考虑一下扑克牌,如何用电脑编程做到高效而完美地洗牌呢? 要求是代码少.效率高,洗牌的结果要同时 ...

  4. 洗牌算法shuffle

    对这个问题的研究始于一次在群里看到朋友发的洗牌面试题.当时也不知道具体的解法如何,于是随口回了一句:每次从剩下的数字中随机一个.过后找相关资料了解了下,洗牌算法大致有3种,按发明时间先后顺序如下: 一 ...

  5. 扑克游戏的洗牌算法及简单测试

    2019独角兽企业重金招聘Python工程师标准>>> 我在学习<写给大家看的C语言书>这本书时,对书后面附录的一个扑克游戏程序非常感兴趣.源代码在帖子最后. PS:这本 ...

  6. 随机洗牌算法+matlab,洗牌算法及 random 中 shuffle 方法和 sample 方法浅析

    对于算法书买了一本又一本却没一本读完超过 10%,Leetcode 刷题从来没坚持超过 3 天的我来说,算法能力真的是渣渣.但是,今天决定写一篇跟算法有关的文章.起因是读了吴师兄的文章<扫雷与算 ...

  7. 洗牌算法(高纳德置乱算法)记录

    原理:将最后一个数和前面n-1个数中的一个数进行交换,然后倒数第二个和前面n-2个数中的一个数进行交换.以此类推 洗牌算法的python实现 import random lst = list(rang ...

  8. Knuth高效洗牌算法

    今天在做一个游戏需求的时候碰到一个问题,问题很简单,给定75个球,编号1-75,需要保证初始化的时候位置是随机的. 显然,我们可以初始化一个数组A,把75个数放进去,然后做一个shuffle函数随机交 ...

  9. 洗牌算法(Knuth-Durstenfeld Shuffle)

    1 原理   洗牌算法的思想很简单.给你一个数组[1,2,3,4,5,6,7][1,2,3,4,5,6,7][1,2,3,4,5,6,7]让你洗一洗,思路就是交换,从第一个元素开始,与包括它以及在它之 ...

最新文章

  1. mac 使用svn记录
  2. SQL Server 2014图文安装教程
  3. 七牛上传图片html,使用七牛云上传图片
  4. [深度学习] 分布式Tensorflow 2.0 介绍(二)
  5. 2017.9.13 序列统计 思考记录
  6. 【点阵液晶编程连载三/B】点阵LCD 的驱动与显控
  7. warning C4482: 使用了非标准扩展: 限定名中使用了枚举
  8. 吴恩达机器学习视频学习笔记(4)
  9. 回答cad转pdf格式的简易方法
  10. Altium Designer20下绘制封装、布局、布线及裁板等操作
  11. windows管理信息服务器不可用,Windows提示 错误: RPC 服务器不可用 解决方法。
  12. 【百页AI报告】2017人工智能现状、创业图景与未来(98PPT)
  13. 【洛谷】P1008 [NOIP1998 普及组] 三连击
  14. python 随机森林分类 DecisionTreeClassifier 随机搜索优化参数 GridSearchCV
  15. 债务大爆发,中国30%家庭不堪一击!
  16. 生物信息百jia软件(25):quast
  17. 彩超探头频率高低的区别_【干货】超声探头及使用技巧
  18. Overleaf编译问题
  19. 实时数仓利器之Doris
  20. 好用的linux终端工具,推荐7款好用的终端工具

热门文章

  1. C++ array
  2. 如何将Excel中的数据粘贴到cxGrid中
  3. linux shell awk用法
  4. Django cms 教程五:添加内容
  5. 装linux系统和安装工具
  6. 刷了一个半月算法题,我薪资终于Double了
  7. Vue权限管理解决方案
  8. SRM 576 D2 L3:CharacterBoard2
  9. 996的压力下,程序员还有时间做副业吗?
  10. 专业的web打印插件