概率取样问题

  问题:程序输入两个整数m和n,其中m<n。输出是0~n-1范围内的m个随机整数的有序列表,不允许重复,要求每个选择出现的概率相等。
  (1)扫描算法:扫描0~n-1,通过一个概率测试来对每个整数进行选择,可保证输出结果是有序的。考虑m=2,m=5的情况。选择的0的概率为2/5,通过语句if(bigrand()%5)<2来实现。若选择了0,则在剩下的4个数中以1/4的概率选择一个数。若未选择0,则以2/4的概率选择下一个数,这样就能保证恰好能选出m个整数。这里bigrand()返回一个很大的随机整数,远大于m和n。一般来说,如果要从r个剩余整数中选择s个,我们以概率s/r选择下一个整数。

  显然,算法的运行时间为O(n)。
  (2)基于集合的算法:在一个初始为空的集合里面插入随机整数,直到个数足够,核心问题是如何实现集合S。我们可以考虑有序链表、二叉树等数据结构,但最直接的办法是利用C++标准模板库中的set容器。

  C++ STL规范要求每次插入操作都在O(logm)时间内完成,而遍历集合则需要O(m)时间。因此整个程序需要O(mlogm)时间(当m相对于n较小时)。但是该数据结构的空间开销比较大。
  当n比较大而m接近于n时,基于集合的算法需要生成大量的随机数,而其中很多随机数都要丢掉(因为之前集合中已经存在这个数了),这导致很多不必要的运行时间开销。Bob Floyd给出了一个算法,使得即使在最坏情况下也只使用m个随机数。如下(C++实现):

  (3)排序算法:生成随机整数的有序子集的另一种方法是把包含整数0~n-1的数组顺序打乱,然后把前m个元素排序输出。

  算法需要n个元素的内存空间和O(n+mlogm)的时间。
  关键算法设计思想:扫描策略、概率测试(随机数生成)、集合数据结构、搜索策略、排序策略。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Python中,我们经常需要从一个列表或数据集中随机抽取一些元素,以进行随机实验、样本测试等操作。Python提供了许多有用的工具和函数来进行随机取样。常用的三种随机抽样方法包括简单随机抽样、有放回随机抽样和无放回随机抽样。简单随机抽样是从一个包含N个元素的总体中随机地抽取n个元素构成样本,每个元素被抽取的概率相等,且抽取的元素互相独立。有放回随机抽样是在抽取一个元素后将其放回总体中,使得下一次抽取时该元素仍然有机会被选中。无放回随机抽样是在抽取一个元素后不再将其放回总体中,使得下一次抽取时该元素不再有机会被选中。 对于简单随机抽样,我们可以使用Python的random模块中的sample函数。该函数接受一个列表(或其他可迭代对象)和要抽取的样本大小,返回一个随机抽取的样本列表。示例代码如下: ```python import random population = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] sample_size = 5 sample = random.sample(population, sample_size) print #### 引用[.reference_title] - *1* *3* [python随机抽样_掌握python中的随机抽样](https://blog.csdn.net/weixin_26736149/article/details/108915780)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [Python随机抽样的三种方法及自定义封装函数实现](https://blog.csdn.net/ai52learn/article/details/130833730)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值