随机算法

Fisher-Yates 洗牌算法

Fisher-Yates 洗牌算法是一个用来将一个有限集合生成一个随机排列的算法(数组随机排序)。这个算法生成的随机排列是等概率的,同时这个算法非常高效。

算法步骤:

1.写下从 1 到 N 的数字
2.取一个从 1 到剩下的数字(包括这个数字)的随机数 k
3.从低位开始,得到第 k 个数字(这个数字还没有被取出),把它写在独立的一个列表的最后一位
4.重复第 2 步,直到所有的数字都被取出
5.第 3 步写出的这个序列,现在就是原始数字的随机排列

// 反向或者正向洗牌效果相同。
// 给定有限个数字的数组shuffled
// 反向洗牌:
for (int i = n - 1; i >= 0; --i) {
    swap(shuffled[i], shuffled[rand() % (i + 1)]);
}

// 正向洗牌:
for (int i = 0; i < n; ++i) {
    int pos = rand() % (n - i);
    swap(shuffled[i], shuffled[i+pos]);
}

时间复杂度为O(n)

蓄水池抽样算法

举例:当内存无法加载全部数据时,如何从包含未知大小的数据流中随机选取k个数据,并且要保证每个数据被抽取到的概率相等。

k=1时:

我们每次只能读一个数据。假设数据流含有N个数,我们知道如果要保证所有的数被抽到的概率相等,那么每个数抽到的概率应该为 1/N。每次只保留一个数,当遇到第 i 个数时,以 1/i的概率保留它,(i-1)/i的概率保留原来的数。

举例说明: 1 - 10:

  • 遇到1,概率为1,保留第一个数。
  • 遇到2,概率为1/2,这个时候,1和2各1/2的概率被保留
  • 遇到3,3被保留的概率为1/3,(之前剩下的数假设1被保留),2/3的概率 1 被保留,(此时1被保留的总概率为 2/3 * 1/2 = 1/3)
  • 遇到4,4被保留的概率为1/4,(之前剩下的数假设1被保留),3/4的概率 1 被保留,(此时1被保留的总概率为 3/4 * 2/3 * 1/2 = 1/4)

k=m时:

与上面相同,但概率每次×m

1.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值