• 随机取样


    问题定义:

    输入:两个整数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 }
  • 相关阅读:
    C语言基础--函数
    C语言基础--for循环
    C语言基础--while循环
    C语言基础--switch
    iOS UIView常用方法和属性
    iOS UIView简单缩放动画
    Android ListView动态改变Item高度
    iOS UILabel自定义行间距时获取高度
    iOS UILable高度自适应
    iOS 简单block的使用
  • 原文地址:https://www.cnblogs.com/lwyeah/p/8589276.html
Copyright © 2020-2023  润新知