水库抽样算法-亚线性空间算法

水库抽样算法定义:

  有一组数据,这组数据的大小未知而且需要输出这组数据的k个均匀抽样,其中要求如下:

    (1)仅扫描数据一次

    (2)空间复制性为O(k)

    (3)扫描都数据的前n个数字时(n>k),保存当前已扫描数据的k个均匀抽样

分析如下:

  第一步:申请一个长度为k的数组A保存抽样

  第二步:保存首先接收到的k个元素

  第三步:当接收到第i个新元素t时,以k/i的概率随机替换A中的元素(即生成[1,i]间随机数j,若j<=k,则以t替换A[j])

性质:

  (1)该采样是均匀的

    

  (2)空间复杂度为O(k)

算法的伪代码如下:

Init : a reservoir with the size: k
        for    i= k+1 to N
            M=random(1, i);
            if( M <</SPAN> k)
                 SWAP the Mth value and ith value
       end for

 

程序示例如下(k=10):

  int?[] k = new int?[10];//k 相当于数组A
            int i = 0;
            while (true)
            {
                int? number = Convert.ToInt32(Console.ReadLine());//number 相当于t
                i++;
                if ((i-1) < k.Length)
                {
                    k[i-1] = number;
                }
                else
                {
                    Random random = new Random(i);
                    int j = random.Next(1, i + 1);
                    if (j <= k.Length)
                    {
                        k[j - 1] = number;
                    }
                    //满了
                }
                Show(k);
            }
算法代码

 

测试结果:

 

posted @ 2015-07-29 15:56  聆听的风声  阅读(1433)  评论(0)    收藏  举报