从很长的数据流等概率随机采样
“给出一个数据流,这个数据流的长度很大或者未知。并且对该数据流中数据只能访问一次。请写出一个随机选择算法,使得数据流中所有数据被选中的概率相等。” 在搜索引擎等相关领域也会被问到哦
假设数据流长度为n,那么我们希望数据流中的每个数据都是以 1/n 的概率返回。
相关题目:
382. 链表随机节点
398. 随机数索引
不合适的但容易想到的两种方法:
- 直观的做法是生成一个 1-n 的随机数 i,代表我们想取第 i 个数据。但是这个前提是我们知道了数据流的长度。通常来说,数据流只会被读取一次,要求在读取的过程中就实现随机采样,因此该方法是不现实的。
- 对于第i个数据,以概率 1 / n-i 返回。这样对于返回第i个数据的概率,就是前面的不返回*当前返回 = n-i / n * 1 / n-i = 1 / n,但是这样做的前提也是要知道n
两种正确做法:
1.蓄水池法:对于第i个数据,以 1 / i 的概率替换池中保留的数据。
假设现在有数据流 1,2,3,4。那么第一个数据1被采样的概率是后面都不被替换 = 1/2 * 2/3 * 3/4 = 1/4,第二个数据2被采样的概率是替换1且后面不被替换 = 1/2 * 2/3 * 3/4 = 1/4。第三个数据被采样的概率是无论池中为何数,轮到自己时要替换且后面不再被替换 = 1/3 * 3/4 = 1/4。第四个数据被采样的概率 = 1/4 。
更加严格的证明

本文介绍如何从长数据流中实现等概率随机采样,包括蓄水池法及随机数法两种有效方法,并解释其工作原理。


被折叠的 条评论
为什么被折叠?



