随机取样问题

本文详细解读了计算机程序设计艺术中关于随机取样的问题,包括确定数目元素的随机取样与不确定数目元素的随机取样,并提供了一个具体算法实现。通过数学归纳法证明了算法的正确性,即确保取样的元素数量、唯一性和随机性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

随机取样问题,在《计算机程序设计艺术》(volume 2 chapter 3)中得到了详细的讲解,关于该问题的详细探讨可以翻阅该书相应章节。

随机取样问题可以分为:

1、             确定数目元素的随机取样,可以表述为:从N个元素中获得K个相异且随机的元素。

2、             不确定数目元素的随机取样,可以表述为:从一个数据流中获得k个相异且随机的元素。

其实第二个问题包含着第一个问题,我们只要探讨第二个问题即可,我直接给出下面的算法吧,首先要注意取样问题的描述:“k个”“相异”“随机”,代码如下:

                T* random_sample(stream s, int k)

{

      T* rand_list=new T[k];

      int i=k;

      s.open();

      /*store first k elements in stream*/

      while(k-->=0)

            rand_list[i]=s.next();

      i=k;

      while(!s.end())

      {

            i++;

            int idx=rand(0, i-1);//create random number [0, i-1]

            if(idx<=k-1)//[0,k-1]

                  rand_list[idx]=s.next();

      }

}

下面对其正确性进行证明,正确性应该保证“k个”“相异”“随机”,前两个条件显然成立,开始状态前两个状态就成立,函数执行过程中,每次替换的元素都不相同(我们认为在stream中不同位置的元素不同),对于“随机”的证明可以使用数学归纳法进行:

                待证明问题,对于任意n>=k,经过上述方法后,得到的结果中任何一个元素出现的概率均为k/n

1、 n=k时,rand_list[]中存储前k个元素,p=k/n=k/k=1成立。

2、 假设当n=i时,命题成立:i个元素出现在rand_list[]中的概率为k/i

n=i+1时,执行上述算法,我们只关注最后一步:对于第i+1个元素的操作。

对第i+1个元素执行上述算法之前,对于前i个元素中任意一个元素,它们在rand_list[]中出现的概率为k/i,我们以k/(i+1)的概率去替换rand_list[]中的元素,前i个元素中任意一个元素被替换的概率为:

        k(1/i) * ( 1/(i+1))

i个元素中任意一个元素最终被取到的概率:

        k/I - k(1/i) * ( 1/(i+1)) = k/(i+1)

对于第i+1个元素,它被取到的概率可以直接计算得到:

        P(i+1)=k/(i+1)

所以当n=i+1时,上述命题也成立。

下面给两个相关的题目:

1、 给定一个未知长度的整数流,如何随机选取一个数

2、 给定一个数据流,其中包含无穷尽的搜索关键字(比如,人们在谷歌搜索时不断输入的关键字)。如何才能从这个无穷尽的流中随机的选取1000个关键字?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值