从一个未知容量的投票木箱中,随机抽取m张投票
2016-11-01 11:43
183 查看
昨天晚上参加了喜马拉雅的笔试,看完这题我一脸愣逼,当时的第一个想法是类似线段树,每次从m个数中随机一个数进入到上一层。。。最后发现要保证等概率的问题对长度实质是由要求的。
回去果断百度,发现这题其实在11年的百度笔试题中就出现过,惭愧。
原题大概是这样的:
一个服务器一天内会收到很多request,但是服务器只能存放m个request,试设计一种算法并证明,使得在时时的reqest中选择m个保存,并保证最后各个request被选中的概率为大致相同。记住,不到最后,不知道request的总数n。
解题方案:
首先将前m个request依次放入服务器的大小为m的备选集合中,当第m+1个来临时,利用轮盘算法来保证第m+1个有m/(m+1)的概率能够进入到备选集合中,如果满足进入条件再将备选集合中m个request中等概率选择一个替换进行替换。当第m+i个来临时,有
m/(m+i)的概率能够进入到备选集合中,并在已保存的m个request中等概率选择一个替换之。 依次类推,第N个request以m/N的概率被选择,并在已保存的m个request中等概率选择一个替换之。最终每个request被选择的概率为m/n。
证明:
当N=m+1时,第m+1个选中的概率为m/(m+1);
而第i个(i <= N)被选中的概率为:第N个没有机会进入到集合中的概率+第N个进入到集合中的概率*第i
个数据不会被替换掉的概率。
得:1/(m+1) + m/(m+1) * (m-1)/m = m/(m+1);
假设当N = n时,每个request被选择的概率为m/n;
那么接下来我们只需要证明当N = n+1时,每个request被选择的概率为m / (n+1),即可.
第n+1个选中的概率为m/(n+1);
此时第i个(i <= N)request被选择的概率为:在N = n时,第i个能够被保留下来的概率* (第n+1个没有机会进入到集合中的概率+第n+1个进入到集合中的概率*第i
个数据不会被替换掉的概率)。
得:(m/n)* ( (n+1-m)/(n+1) + m/(n+1) * (m-1)/m )= (m / n)*(n/(n+1))= m/(n+1)。
证毕。
回去果断百度,发现这题其实在11年的百度笔试题中就出现过,惭愧。
原题大概是这样的:
一个服务器一天内会收到很多request,但是服务器只能存放m个request,试设计一种算法并证明,使得在时时的reqest中选择m个保存,并保证最后各个request被选中的概率为大致相同。记住,不到最后,不知道request的总数n。
解题方案:
首先将前m个request依次放入服务器的大小为m的备选集合中,当第m+1个来临时,利用轮盘算法来保证第m+1个有m/(m+1)的概率能够进入到备选集合中,如果满足进入条件再将备选集合中m个request中等概率选择一个替换进行替换。当第m+i个来临时,有
m/(m+i)的概率能够进入到备选集合中,并在已保存的m个request中等概率选择一个替换之。 依次类推,第N个request以m/N的概率被选择,并在已保存的m个request中等概率选择一个替换之。最终每个request被选择的概率为m/n。
证明:
当N=m+1时,第m+1个选中的概率为m/(m+1);
而第i个(i <= N)被选中的概率为:第N个没有机会进入到集合中的概率+第N个进入到集合中的概率*第i
个数据不会被替换掉的概率。
得:1/(m+1) + m/(m+1) * (m-1)/m = m/(m+1);
假设当N = n时,每个request被选择的概率为m/n;
那么接下来我们只需要证明当N = n+1时,每个request被选择的概率为m / (n+1),即可.
第n+1个选中的概率为m/(n+1);
此时第i个(i <= N)request被选择的概率为:在N = n时,第i个能够被保留下来的概率* (第n+1个没有机会进入到集合中的概率+第n+1个进入到集合中的概率*第i
个数据不会被替换掉的概率)。
得:(m/n)* ( (n+1-m)/(n+1) + m/(n+1) * (m-1)/m )= (m / n)*(n/(n+1))= m/(n+1)。
证毕。
相关文章推荐
- C#--第九周实验--任务3--定义一个静态成员方法,使用Random实现从一组数中随机抽取n个不重复的数。
- 阿里巴巴面试算法题:有一个函数int getNum(),每运行一次可以从一个数组V[N]里面取出一个数,N未知,当数取完的时候,函数返回NULL。现在要求写一个函数int get(),这个函数运行一次可以从V[N]里随机取出一个数,而这个数必须是符合1/N
- 未知长度链表数据随机抽取问题
- 从一个文件中随机抽取N行方法
- C#--第九周 任务3--定义一个静态成员方法,使用Random实现从一组数中随机抽取n个不重复的数
- perl实现从一个文件中随机抽取n行
- 有一个函数int getNum(),每运行一次可以从一个数组V[N]里面取出一个数,N未知,当数取完的时候,函数返回NULL。现在要求写一个函数int get(),这个函数运行一次可以从V[N]里随机
- 【转】从一副扑克牌中随机抽取N张
- 如何从一个表中随机抽取不重复的记录
- 随机从长度未知的数组中抽取数字,且保证每个元素被抽到的概率相同
- flash 与随机性:随机抽取
- 按给定几率进行随机抽取的js代码
- SQL Server 随机数,随机区间,随机抽取数据rand(),floor(),ceiling(),round(),newid()函数等
- Oracle中随机抽取N条记录
- 从文件里随机抽取XX行
- 用MATLAB实现1到10000的数组,随机从中抽取8000个元素
- MYSQL随机抽取查询 MySQL Order By Rand()效率问题
- 随机抽取学生,按钮不起作用
- Oracle中随机抽取N条记录
- 未知长度链表中随机取数