• 13概率问题


        题目描述:一个文件中含有多个元素,只能遍历一遍,要求等概率随机取出其中之一。

     

        先讲一个例子,5个人抽5个签,只有一个签意味着“中签”,轮流抽签,那么这种情况,每个人中签的概率分别是多大呢?

        第一个人中签的概率是1/5,

        第二个人中签的情况只能在第一个人未中时才有可能,所以他中的概率是4/5 * 1/4 = 1/5(4/5表示第一个人未中,1/4表示在剩下的4个签里中签的概率),所以,第二个人最终的中签概率也是1/5,

        同理,第三个人中签的概率为:第一个人未中的概率X 第二个人未中的概率X第三个人中的概率,即为:4/5 * 3/4 * 1/3 = 1/5,

        一样的可以求出第四和第五个人的概率都为1/5,也就是说先后顺序不影响公平性。

     

        回到最开始的问题,一个文件中包含n个数据,而且n是不可知的,那么下面的思路就不太可行:随机选取1-n之间的任意一个数i = rand(1,n),然后返回文件中的第i个数。

     

        此题思路如下:

        顺序遍历文件,当前遍历的元素为第i个元素,picked表示之前选取了的某一个元素,此时生成一个随机数r=rand(),那么r%i == 0的概率是 。当r%i== 0的时候,将picked替换为当前值,否则扫描下一个元素直到文件结束。

     

    伪代码如下:

    ElementRandomPick(file)

             int length = 1;

             While( length <= file.size )

                      if( rand() % length == 0)

                            picked = File[length];

                              length++;

             Return picked

     

     

        上面这种策略,当遍历完所有的n个数之后,任取一数的概率都是相同的 ,

       用归纳法证明:

       在遍历第1个元素的时候,即length为1,那么rand() % length == 0的概率为1,所以,目前取第1个的概率为1。

        遍历到第2个元素时,length=2,rand() % length == 0的概率为1/2 , 所以目前,取第2个数的概率为1/2 ,取第一个数的概率为1*(1-(1/2) )= 1/2

        遍历到第i个元素时,length=i, rand() % length== 0的概率为1/i , rand() % length != 0的概率为(i-1/i) ,所以目前,取第i个数的概率为1/i 。取第m个数(m<i)的概率是(1/m) *(m/m+1) *(m+1/m+2) *...*(1/i)  = 1/i。

        走到文件最后,每一个元素最终被选出的概率为 1/n 。

    (http://blog.csdn.net/v_july_v/article/details/6712171)

     

  • 相关阅读:
    8月24 杂七杂八
    胡思乱想
    前端思考题
    前端经典面试题
    一些被废弃的东西
    关于设置img图片大小优先级的问题
    关于 removeChild()删除节点
    关于前端基本要求及一些题
    关于 Oracle 11g 先决条件检查失败的解决办法
    《现代前端技术解析》第一章读书笔记(未完成)
  • 原文地址:https://www.cnblogs.com/gqtcgq/p/7247174.html
Copyright © 2020-2023  润新知