使用时间窗口计算移动平均值

时间:2018-12-06 12:57:01

标签: java algorithm

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

//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,所以条目似乎从未被删除?

可能是什么错误?

2 个答案:

答案 0 :(得分:1)

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

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();
  }

}

答案 1 :(得分:1)

最大的问题是您使用HTTP_HOST fr.french-domain.com/(.*) RewriteRule ^fr.french-domain.com/(.*)$ https://www.french-domain.com/fr/$1 [L,R=301] 作为时间戳。

Queue<Float>当前为1544100776456

四舍五入为最接近的浮点数,即1.5441007E12

如您所见,我们丢失了一些数字。您需要等待大约一分钟,然后浮动值才会更改。

您应该在该队列中使用Long或Double。

然后,您必须检查while循环的每个迭代的队列大小> 0,而不仅仅是第一个。