【算法】洗牌算法Fisher–Yates shuffle

【算法】洗牌算法Fisher–Yates shuffle

C#语言一般都是调用随机函数Random.Next函数,在一个范围内随机出一个数字。但是当我们需要将n个数据随机选择k个数。怎么办呢?

方案一:随机出一个数,然后从剩下的数里面接着随机。

方案二:每次都从n个数据里面随机出一个数,遇到重复的,放回去。接着随机,直到随机出k个数。

我们的目的是不管用哪个方案,我们都需要保证选出的数要是等概率的。

方案一:取第1个数是1/n,第二个数是1/(n-1)…1

方案二:最坏的情况下我们从100个里面随机出99个,越到后面随机出来的重复率越高。

Fisher–Yates shuffle

Fisher–Yates shuffle算法是高效和等概率的一个洗牌算法。其核心思想是从1到n之间随机出一个数和最后一个数(n)交换,然后从1到n-1之间随机出一个数和倒数第二个数(n-1)交换…假设我们有5个数0,1,2,3,4

0,1,2,3,4

1.从[0,4]这5个位置中(包含0和4)随机出一个数(比如是3)和4号交换。

0,1,2,43

第4号位置放3的概率就是1/5

2.从[0,3]这4个位置中(包含0和3)随机出一个数(比如是0)和3号交换。

4,1,2,0,3

第3号位置放0的概率就是(4/5)*(1/4)=1/5

3.从[0,2]这3个位置中(包含0和2)随机出一个数(比如是0)和2号交换。

2,1,4,0,3

第2号位置放4的概率就是(4/5)x(3/4)x(1/3)=1/5

4.从[0,1]这2个位置中(包含0和1)随机出一个数(比如是0)和1号交换。

12,4,0,3

第1号位置放2的概率就是(4/5)x(3/4)x(2/3)x(1/2)=1/5

5.从[0,0]这1个位置中(包含0和0)随机出一个数(比如是0)和0号交换。

1,2,4,0,3

第0号位置放1的概率就是(4/5)x(3/4)x(2/3)x(1/2)=1/5

其实第5步骤就是不用交换了。

那么我们再回到之前的问题,取出k个数。其实我们将这几个数字洗完之后,即已经随机打乱了。所以从里面按照顺序取出k个数即可。

如果本文对你有所帮助,欢迎赞赏~~~

欢迎关注微信公众号:Unity游戏开发笔记
在这里插入图片描述
QQ群:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值