【发布时间】:2019-03-16 02:58:02
【问题描述】:
我正在使用 GPS 开发一个 android 应用程序。我想实现一个功能,显示用户在 1/5/15 分钟内的平均速度。类似于 unix 上的 CPU 负载。我可以通过逐秒累积行驶距离并将其除以经过的时间来轻松计算平均值,但我想不出一种计算移动平均值的聪明方法。
显然,我可以通过每秒将最后一个位置和当前位置之间的距离放入一个数组中来完成 id,同时删除最旧的值。
我正在寻找一种巧妙的方法。
【问题讨论】:
我正在使用 GPS 开发一个 android 应用程序。我想实现一个功能,显示用户在 1/5/15 分钟内的平均速度。类似于 unix 上的 CPU 负载。我可以通过逐秒累积行驶距离并将其除以经过的时间来轻松计算平均值,但我想不出一种计算移动平均值的聪明方法。
显然,我可以通过每秒将最后一个位置和当前位置之间的距离放入一个数组中来完成 id,同时删除最旧的值。
我正在寻找一种巧妙的方法。
【问题讨论】:
这是一种非常简单的方法:
如果您每秒采样一次位置,则将 901 个样本排在队列中,这相当于 15 分钟(以及 1 分钟)。 位置 0 是最近的测量值,实际上是您的当前位置。
对于过去 X 分钟的平均速度:
s = X * 60;
point1 = postion_queue[0]; // this is your current position
point2 = postion_queue[s]; // this is your position s seconds ago
d = distance_between_points(point1, point2);
speed = d / s;
speed 现在是每秒距离单位,转换为 mph、kph 或您需要的任何单位。不同的 X 值可用于 1 到 15 分钟之间的任何平均值。
【讨论】:
正如您已经建议的那样,您需要存储整个时间跨度的所有值。原因是您需要以某种方式“忘记”旧值对移动平均线的贡献。如果您不知道这些值在哪里(即如果您不存储它们),您就无法准确地做到这一点。
在您的情况下,15 分钟内每秒 1 个值相当于 15 * 60 = 900 个数据点,应该没问题。
请注意,您不需要在每次更新时对整个数组进行求和:您可以根据数据点的数量、新值和您当时“忘记”的值来计算新的移动平均值:
new_average = (n * old_average - x_forget + x_new) / n
这里,n 是数据点的数量(在您的情况下为 900),x_forget 是您“忘记”的值,x_new 是最新值。然后,您从阵列的前面删除x_forget,并在最后存储x_new。您可能希望使用通过链表实现的队列而不是数组。
【讨论】: