随机取样

问题定义:

输入:两个整数m和n,其中m<n。

输出:[0,n-1]范围内m个整数的有序列表,不允许重复。


1、假如我们拥有一个能返回很大的(远大于m和n)的随机整数的函数bigrand()

顺序考虑整数0...n-1,并通过bigrand()的测试对每个整数进行选择,这样保证输出的数为有序的。

考虑m=2,n=5的情况,选择第一个整数0的概率为2/5,可以通过bigrand() % 5 < 2来以2/5的几率选择整数0;再考虑整数1,不能再以2/5的几率选择,否则不能保证选择的结果一定为两个(虽然这样选择的期望确实为两个),在选择0的情况下以1/4的概率选择1,在未选择0的情况下以2/4的概率选择1。

通过对每个数都以这样的概率进行考虑,可以保证不会选择更多的整数,因为当待选择的个数为0时,选取概率为0;也不会选择更少的整数,当剩余的数个数与待选的数的个数相同时,选取概率为1,必然选择。

 1 void getknuth(int m, int n){
 2     int i;
 3 
 4     for(i=0; i<n; i++){
 5         if(bigrand() % (n-i) < m){
 6             printf("%d ", i);
 7             m--;
 8         }
 9     }
10 }

 2、一个复杂度更低的算法

伪代码如下:

1 initialize set S to empty
2 size = 0
3 while size < m do
4     t = bigrand() % n
5     if t is not in S
6         insert t into S
7         size++
8 print the elements of S in sorted order

3、利用交换随机打乱数组的顺序,选取前m个元素作为结果

randint(i, j)函数返回i...j之间随机整数

伪代码如下:

 1 void genshuf(int m, int n){
 2     int i, j;
 3     int *x = new int[n];
 4     for(i=0; i<n; i++){
 5         x[i] = i;
 6     }
 7     for(i=0; i<m; i++){
 8         j = randint(i, n-1);
 9         swap(i, j);
10     }
11     sort(x, x+m);
12     print the first m elements;
13 }

 

转载于:https://www.cnblogs.com/lwyeah/p/8589276.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值