等概率无重复的从n个数中选取m个数

博客探讨了如何从n个数中等概率无重复地选取m个数的问题,介绍了两种方法:一是根据概率s/r选择下一个数,保证每个数被选中的概率为m/n;二是利用集合思想,按等概率选择不在集合中的随机数,直至集合元素达到m个。此外,还讨论了在未知总数n的情况下,如何进行等概率选择的方法。

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

问题描述:程序的输入包含两个整数m和n,其中m<n。输出是0~n-1范围内的m个随机整数,要求:每个数选择出现的概率相等,且按序输出。

学习过概率统计的同学应该都知道每一个数字被抽取的概率都应该为m/n. 那么我们怎么构造出这样的概率呢?在《编程珠玑》上面是这样解析的:

  依次考虑整数0,1,2,.....,n-1,并通过一个适当的随机测试对每个整数进行选择。通过按序访问整数,我们可以保证输出结果是有序的。 假如我们考虑m = 2,n = 5的情况,那么选择的每一个数字的概率都应该是2/5,我们怎么样才能做到呢?不慌张,慢慢来。

  下面给出我的分析过程:在0,1,2,3,4这五个数字中,我们依次对每一个数进行分析,第一次遇到0时,它的选择概率应该是2/5,如果选中了,我们开始测试第二个数1,这个时候因为1选中了,所以1这个数字的选中概率就变小了,变成1/4了,有人说这似乎不对吧,因为题目说让每一个数字选中的概率是一样大的,而现在?一个2/5,一个1/4,这怎么行呢?其实不是这样的,认真思考一下就知道了,数字1选中的概率等于什么? 数字1选中的概率p(1) = 数字0选中的概率 * (1/4) + 数组0没选中的概率*(2/4)这样推算下 (2/5 * 1/4) + (3/5 * 2/4) = 8/20 = 2/5 。这不就一样了吗?呵呵!下面给出来自Knuth的《The Art of Computer Programming, Volume2:Seminumerical Algorithms》的伪代码:

 

select = m
remaining = n
for i = [0,n)
     if (rand() % remaining) < select
             print  i
             select --
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值