13概率问题

来源:互联网 发布:上古世纪女精灵数据 编辑:程序博客网 时间:2024/06/04 18:20

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

 

    先讲一个例子,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)

 

0 0