我实施水库实施

时间:2014-07-03 20:36:50

标签: java random-sample

你好,基于油藏采样算法的weki描述,我这样做了,似乎没有按预期工作。算法在这里: http://en.wikipedia.org/wiki/Reservoir_sampling

哪里可能错了?

public int[] sample(int k, int[] array) {

    int[] reservior = new int[k];

    int i;
    for(i=0; i<k; i++){
        reservior[i] = array[i];
    }

    int j=0;
    Random random = new Random(System.currentTimeMillis());
    for(; i<array.length; i++){
        j = random.nextInt(i);

        if(j< k){
            reservior[j] = array[i];
        }
    }

    return reservior;
}

这是我的测试代码。我创建了一个包含0 ... 9元素的数组,并调用函数&#34; sample(k,array)&#34; K = 5。其中一个看起来如下。显然,它不是随机的,具有相同的概率。

0 9 2 3 5

0 9 2 3 5

0 6 8 7 4

0 6 8 7 4

0 6 8 7 4

0 6 8 7 4

0 6 8 7 4

0 6 8 7 4

0 6 8 7 4

0 6 8 7 4

    int size = 10;      
    int[] array = new int[size];

    for(int i=0; i<size; i++){
        array[i] = i;
    }

    int k = 5;
    for(int i=0; i<10; i++){
        int[] reservior = sample(k, array);
        for(int j=0; j<reservior.length; j++){
            System.out.print(reservior[j] + " ");

        }   
        System.out.println();
    }

3 个答案:

答案 0 :(得分:0)

System.currentTimeMillis()返回相同的值超过一毫秒(通常在Windows机器上为10毫秒)。

Random是一个随机生成器。因此,如果您创建一个Random并使用给定值对其进行种子处理,它将给出一个确定的值序列。由于您总是重新创建它并使用相同的值对其进行播种,因此您始终会获得相同的值序列。

使用Random的唯一实例,创建一次,而不是种子。

答案 1 :(得分:0)

您正在快速调用样本,以便在几次运行中以相同的值播种。这就是为什么你看到价值最终会发生变化的原因,而不是每次通话。

您可以随机设置一个私有类变量,以便它只播种一次(并且您不需要自己播种...默认情况下它会使用System.nanoTime(),这会使更少< / i>一个问题本身)。这个解决方案还节省了一点内存,并且不必要地初始化一个新的Random实例花费了一些CPU周期。

public class ReservoirExample {
  private Random random = new Random();

  public int[] sample(int k, int[] array) {

    int[] reservior = new int[k];

    int i;
    for(i=0; i<k; i++){
      reservior[i] = array[i];
    }

    int j=0;
    for(; i<array.length; i++){
      j = random.nextInt(i);

      if(j< k){
        reservior[j] = array[i];
      }
    }

    return reservior;
  }
}

答案 2 :(得分:0)

谢谢,按照上面的建议,我运行样本()10000次,并得到这些数字。第一列是整数,第二列表示在函数的1000次调用中对此整数进行采样的次数。它似乎仍然不是均匀分布的数组中整数的随机采样。

我不确定算法的实现是否存在某些问题或其他问题。

1 4445

2 4390

3 4548

4 4435

5 5588

6 5505

7 5560

8 5553

9 5559