Fisher–Yates随机置乱算法也被称做高纳德置乱算法,通俗说就是生成一个有限集合的随机排列。Fisher-Yates随机置乱算法是无偏的,所以每个排列都是等可能的,当前使用的Fisher-Yates随机置乱算法是相当有效的,需要的时间正比于要随机置乱的数,不需要额为的存储空间开销。

一、算法流程:
需要随机置乱的n个元素的数组a:
for i 从n-1到1

j <—随机整数(0 =< j <= i)

交换a[i]和a[j]

​ end

二、实例

各列含义:范围、当前数组随机交换的位置、剩余没有被选择的数、已经随机排列的数

Range Roll Scratch Result
1 2 3 4 5 6 7 8

第一轮:从1到8中随机选择一个数,得到6,则交换当前数组中第8和第6个数

Range Roll Scratch Result
1 - 8 6 1 2 3 4 5 8 7 6

第二论:从1到7中随机选择一个数,得到2,则交换当前数组中第7和第2个数

Range Roll Scratch Result
1 - 7 2 1 7 3 4 5 8 2 6

下一个随机数从1到6中摇出,刚好是6,这意味着只需把当前线性表中的第6个数留在原位置,接着进行下一步;以此类推,直到整个排列完成。

Range Roll Scratch Result
1 - 6 6 1 7 3 4 5 8 2 6
1 - 5 1 5 7 3 4 1 8 2 6
1 - 4 3 5 7 4 3 1 8 2 6
1 - 3 3 5 7 4 3 1 8 2 6
1 - 2 1 7 5 4 3 1 8 2 6

截至目前,所有需要的置乱已经完成,所以最终的结果是:7 5 4 3 1 8 2 6

package simpleGa;import java.util.Arrays;
import java.util.Random;public class Test {public static void main(String[] args) {int[] arr = new int[10];int i;//初始的有序数组System.out.println("初始有序数组:");for (i = 0; i < 10; i++) {arr[i] = i + 1;System.out.print(" " + arr[i]);}//费雪耶兹置乱算法System.out.println("\n" + "每次生成的随机交换位置:");for (i = arr.length - 1; i > 0; i--) {//随机数生成器,范围[0, i]int rand = (new Random()).nextInt(i+1);System.out.print(" " + rand);int temp = arr[i];arr[i] = arr[rand];arr[rand] = temp;}//置换之后的数组System.out.println("\n" + "置换后的数组:");for (int k: arr)System.out.print(" " + k);}
}

分析:从运行结果可以看到随着算法的进行,可供选择的随机数范围在减小,与此同时此时数组里的元素更加趋于无序。

四、潜在的偏差

在实现Fisher-Yates费雪耶兹随机置乱算法时,可能会出现偏差,尽管这种偏差是非常不明显的。原因:一是实现算法本身出现问题;二是算法基于的随机数生成器。

1.实现上每一种排列非等概率的出现

在算法流程里 j 的选择范围是从0…i-1;这样Fisher-Yates算法就变成了Sattolo算法,共有(n-1)!种不同的排列,而非n!种排列。

j在所有0…n的范围内选择,则一些序列必须通过n^n种排列才可能生成。

2.Fisher-Yates费雪耶兹算法使用的随机数生成器是PRNG伪随机数生成器

这样的一个伪随机数生成器生成的序列,完全由序列开始的内部状态所确定,由这样的一个伪随机生成器驱动的算法生成的不同置乱不可能多于生成器的不同状态数,甚至当可能的状态数超过了排列,不正常的从状态数到排列的映射会使一些排列出现的频率超过其他的。所以状态数需要比排列数高几个量级。

很多语言或者库函数内建的伪随机数生成器只有32位的内部状态,意味着可以生成2^32种不同的序列数。如果这样一个随机器用于置乱一副52张的扑克牌,只能产生52! = 2^225.6种可能的排列中的一小部分。对于少于226位的内部状态的随机数生成器不可能产生52张卡片的所有的排列。

此文章转载自:https://blog.csdn.net/lhkaikai/article/details/25627161

费雪耶兹(Fisher–Yates) 也被称作高纳德( Knuth)随机置乱算法相关推荐

  1. JS 数组打乱 Fisher–Yates shuffle(费舍尔-耶茨 洗牌)

    原理 : Fisher–Yates shuffle 洗牌算法是什么,为什么满足需求? 这里,我们简单借助图形来理解,非常简单直观.你接下来就会明白为什么这是理论上的完全乱序(图片来源于网络). 首先我 ...

  2. leetcode 519. Random Flip Matrix | 519. 随机翻转矩阵(洗牌算法Fisher–Yates shuffle)

    题目 https://leetcode.com/problems/random-flip-matrix/ 题解 看了答案: 洗牌算法 Fisher–Yates shuffle Fisher–Yates ...

  3. Fisher–Yates shuffle 算法

    简单来说 Fisher–Yates shuffle 算法是一个用来将一个有限集合生成一个随机排列的算法(数组随机排序).这个算法生成的随机排列是等概率的.同时这个算法非常高效. Fisher–Yate ...

  4. 洗牌算法(Fisher–Yates Shuffle and Knuth-Durstenfeld Shuffle)

    一.Fisher–Yates Shuffle 1.算法思想: 从原始数组中随机抽取一个新的数字到新数组. 2.算法描述: 初始化原始数组和新数组,原始数组长度为n(已知): 针对未处理的原始数组元素( ...

  5. js打乱数组内元素顺序(Fisher–Yates shuffle洗牌算法)

    如何将数组内元素顺序打乱呢?这里小shy向大家介绍一种算法. Fisher–Yates shuffle:洗牌算法. 通俗理解: 先将数组最后一位元素作为参考点,将这个参考点和数组其他位置的元素(使用随 ...

  6. 数组洗牌 Fisher Yates

    看播放器代码时发现的这个洗牌算法,再网上查了一番 作用是把数组变成随机序列,原理类似于从牌堆A中随机抽牌放进牌堆B 代码1:  返回一个由(数组下标)组成的数组 function random(len ...

  7. 洗牌算法(Fisher–Yates高纳德置乱算法)

    2019独角兽企业重金招聘Python工程师标准>>> function getRandomInt(min, max) {return Math.floor(Math.random( ...

  8. 关于JavaScript的数组随机排序

    昨天了解了一下Fisher–Yates shuffle费雪耶兹随机置乱算法,现在再来看看下面这个曾经网上常见的一个写法: function shuffle(arr) { arr.sort(functi ...

  9. H5游戏开发:消灭星星

    「消灭星星」是一款很经典的「消除类游戏」,它的玩法很简单:消除相连通的同色砖块. 1. 游戏规则 「消灭星星」存在多个版本,不过它们的规则除了「关卡分值」有些出入外,其它的规则都是一样的.笔者介绍的版 ...

最新文章

  1. Jenkins遇到问题一:jenkins配置权限不对导致无法登陆或者空白页面解决办法
  2. mysql_unbuffered_query的_mysql_query与mysql_unbuffered_query的区别
  3. vscode或cmd:无法将“git”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确
  4. hello程序的运行过程-从计算机系统角度
  5. js 判断一个字符在字符串中出现的次数 - 代码篇
  6. Mac下使用Docker快速搭建pinpont追踪系统APM
  7. 基于局域网快速传输文件
  8. 运输问题的表上作业法
  9. oracle职工工资数据表四表联动,oracle 学习之基础篇(四):多表查询
  10. 微信公众号HTML5接入腾讯云人脸核身
  11. linux win10双系统启动顺序,Windows 10 和 Ubuntu 20.04 双系统 GRUB2 默认启动项的更改...
  12. 全息投影助力餐厅,满足全新市场需求
  13. linux权限管理详解
  14. HTML---bootstrap在线引用地址
  15. 看不懂英文文献,怎么写论文?
  16. web开发权威,一个合格的初级前端工程师需要掌握的模块笔记
  17. 函数调用过程以及栈帧详解
  18. 水滴筹-商业模式画布
  19. 如何精准引流?看完这篇文章你将成为高手
  20. 站控层设备种类和对时方式

热门文章

  1. 论文阅读:《A Wavenet For Speech Denoising》
  2. rails3 新特性 和 RJS评论
  3. 使用KMS批量激活操作系统
  4. canvas生成二维码海报-可配置
  5. Apex开发人员指南
  6. 天龙八部TLBB系列 - 网单获取数据库密码和服务端密码(超简单)
  7. Linphone 查看国家码
  8. c++编程 设置桌面壁纸以及设置壁纸失效的解决办法
  9. 10个自动化测试框架,测试工程师用起来
  10. 28 关于 Finalizer