给定一个巨大的文本文件,写一个程序随机输出文件任意k行(k不大,k行能放入内存),要求每一行出现概率相等,请给出核心算法,算法复杂度以及简要的算法原理说明。
先选中前k个,从第k+1个元素到最后一个元素为止,以k/i(i = k+1,k+2,...,N)的概率选中第i个元素,并且随机替代掉一个原先选中的元素,这样一直遍历完所有的元素之后,得到k个元素。可以保证最后都是随机获取。
原理:每次都是以 k/i 的概率来选择。
证明:假设n-1时候成立,即前n-1个数据被返回的概率都是1/n-1,当前正在读取第n个数据,以1/n的概率返回它。那么前n-1个数据中数据被返回的概率为:(1/(n-1))*((n-1)/n)= 1/n,假设成立。
蓄水池抽样算法:
- 先选取
个元素中的前
个元素,保存在集合
中;
- 从第
个元素开始,每次先以概率
选择是否让第
个元素留下。若第
个元素存活,则从
中随机选择一个元素并用该元素
替换它;否则直接淘汰该元素
;
- 重复1和2,直到结束。最后集合
中剩下的就是保证随机抽取的
个元素。
蓄水池抽样算法正确性证明:
为了证明该算法的正确性,我们要保证算法结束后,原个元素每一个最后存活下来的概率都是
(因为从
个元素中随机抽取
个元素,每个元素被抽中的概率都是
)。形式化地,我们要证明的结论是:在算法的第
轮,前
个元素每一个存活下来的概率都是
。
----------------------------------------
利用数学归纳法:
- 当
时,结论显然成立。
- 当
时,根据算法,元素
存活的概率为
。而对于元素
,有两种情况会使其存活下来:要么元素
直接被淘汰;要么元素
留下,但是没有替换掉元素
。由归纳假设,
时结论成立,故元素
存活的概率为
,得证。