如何消除“估计剩余时间”(和ETA)计算中的“抖动”?

时间:2012-01-15 16:21:01

标签: c# .net progress

我有一个应用程序,在执行后台任务时,会显示一个进度条,其中包含“估计剩余时间”计算(例如“剩余5秒”)和“估计完成时间”(例如“12点完成”: 59:59“),或者我称之为ETA。

计算此ETA的算法基本上采用随时间推移的“滚动平均值”:
1.每个进度事件都会以当前时间添加到队列中 2.经过一段时间(例如10秒)后,项目将从队列中删除 3. ETA是从队列中的第一个和最后一个项目推断出来的 如果您关心,可以使用源代码:ETACalculator.cs

但是,存在抖动问题。随着每个进度事件被添加到计算中,ETA将稍微更新。假设ETA仅改变0.1s。这种小抖动很容易导致ETA“颤动”。例如,我没有看到5s,4s,3s等的平滑进展,而是看到了5-5-5-4-5-4-5-4-4-4-4-4。

我在考虑将更新减少到每秒1次,但进度条不太顺畅,而且我真的希望“实际”减速能够实时显示。

我遇到了一个简单的算法,可以减少这种跳跃的抖动。如何消除抖动?

3 个答案:

答案 0 :(得分:11)

实际紧张进度显示进度分成两个独立的变量。

像现在一样更新紧张的进展。

以固定(相对较快)的间隔,将显示的进度更新为接近实际进度。

一种简单的方法算法是平均两个值

display_progress = (display_progress + actual_progress) / 2 

这会抑制价值以反映过去的价值,而不仅仅是直接价值。

您还可以使用以下方法优化平滑度:

display_progress = (P) * display_progress + (1.0-P) * actual_progress 

其中P0.01.0之间的常数值。

修改

这是可以使用的众多过滤器之一。这个很好,因为它不需要太多记账。

然而,获得完美输出并不是一种选择,因为该缺陷存在于输入中。 “抖动”和“实际减速”之间的差异仅在发生之后才能观察到。

答案 1 :(得分:3)

在没有查看代码的情况下对您的算法不太清楚,但是当您更新ETA时,首先检查当前的ETA,并且只有在新值低于旧值时才更新它。

答案 2 :(得分:0)

这听起来像是要“去抖动”:选择最近X个值中的最小值。