利用时间窗计算移动平均

ncgqoxb0  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(331)

我想计算一个时间窗口内的移动平均值:

//object init
MovingAverageTimeBased movTime = new MovingAverageTimeBased(8000f);

//this gets called every Frame (around 180 FPS -- but varies of course)
movingAvg = movTime.next(value, System.currentTimeMillis());

这是一节课:

public class MovingAverageTimeBased {

    float windowsize;
    Queue<Float> queue;
    Queue<Float> timestampQueue;
    float sum;
    float lastItemDeleted;

    public MovingAverageTimeBased(float windowsize) {
        this.windowsize = windowsize;
        this.queue = new LinkedList<Float>();
        this.timestampQueue = new LinkedList<Float>();

        this.sum = 0;
    }

    public double next(float n, float timestamp) {

        if(queue.size() > 1 && timestampQueue.size() > 1) {

            System.out.println("Timestamp diff- " + (timestamp - (float) timestampQueue.peek()));

             while (timestamp - (float) timestampQueue.peek() > windowsize) {
                    System.out.println("Unqueue item");

                    sum = sum - (float) queue.poll();
                    timestampQueue.poll();
             }
        }

        queue.offer(n);
        timestampQueue.offer(timestamp);

        sum = sum + n;
        return (float) sum / queue.size();
    }

}

我的错误是,条目似乎永远不会被删除,因为时间戳的差异总是0?
可能是什么错误?

i1icjdpr

i1icjdpr1#

最大的问题是你用了 Queue<Float> 为了你的时间戳。 System.currentTimeMillis() 目前为1544100776456
四舍五入到最接近的浮点数,即1.5441007e12
如你所见,我们丢失了一些数字。在浮点值改变之前,您需要等待大约一分钟。
你应该在队列中使用long或double。
然后必须为while循环的每个迭代检查queue size>0,而不仅仅是第一次。

mi7gmzs6

mi7gmzs62#

您的代码是可以的,但是您将时间戳存储为float(float对于时间戳来说不够大)将时间戳存储为long

public class MovingAverageTimeBased {

  long windowsize;
  Queue<Float> queue;
  Queue<Long> timestampQueue;
  float sum;
  float lastItemDeleted;

  public MovingAverageTimeBased(long windowsize) {
    this.windowsize = windowsize;
    this.queue = new LinkedList<Float>();
    this.timestampQueue = new LinkedList<Long>();

    this.sum = 0;
  }

  public double next(float n, long timestamp) {

    if(queue.size() > 1 && timestampQueue.size() > 1) {

      System.out.println("Timestamp diff- " + (timestamp - timestampQueue.peek()));

      while(timestamp - timestampQueue.peek() > windowsize) {
        System.out.println("Unqueue item");

        sum = sum - queue.poll();
        timestampQueue.poll();
      }
    }

    queue.offer(n);
    timestampQueue.offer(timestamp);

    sum = sum + n;
    return (float) sum / queue.size();
  }

}

相关问题