2012-01-15 132 views
6

我有一個應用程序,在執行後臺任務時,會顯示一個帶有「估計剩餘時間」計算(例如「剩餘5秒」)和「預計完成時間」的進度條(例如「12:59完成:59「),或者我稱之爲ETA。如何從我的「估計剩餘時間」(和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-5-4-4-4。

我正在考慮將更新降低到每秒1次,但進度條不那麼流暢,而且我真的很希望實時顯示「實際」減速。

我很難想出一個簡單的算法來減少這種跳動的抖動。我怎樣才能消除抖動?

+0

Winforms? WPF?還有別的嗎?你能發佈相關的代碼嗎? – Oded 2012-01-15 16:22:44

+3

Oblicatory [xkcd參考](http://xkcd.com/612/)。 – Ani 2012-01-15 16:24:09

+0

如果減少,只更新進度。 (即如果我們目前在4以上,不要改回5)。 – 2012-01-15 16:29:10

回答

9

實際的緊張進展分別顯示進度分成兩個單獨的變量。

像現在這樣更新抖動進度。

按照正常(相對較快)的時間間隔,將顯示的進度更新爲方法的實際進度。

一種簡單的方法的算法就是平均兩個值

display_progress = (display_progress + actual_progress)/2 

這將挫傷值,以反映過去的價值,而不僅僅是直接的價值。

您還可以通過使用改進的平滑度:

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

哪裏P0.01.0之間的恆定值。

編輯:

這是許多可以使用過濾器之一。這一個很好,因爲它不需要太多簿記。

然而,越來越完美的輸出不會是一種選擇,因爲這個安全漏洞是在你的輸入。 「抖動」和「實際減速」之間的差異只有在發生後才能觀察到

+1

好主意(一階IIR低通濾波器),但這應該在「剩餘時間」變量上完成,而不是「%進度」變量。 – 2012-01-15 17:57:11

+0

我可以看到這將如何「平滑」進度,這可能是我進度計算的一個很好的補充。但我認爲這仍然會受到ETA外推抖動的影響。即使抖動僅爲「0.00001」,ETA介於「5.00000」和「4.99999」之間時也會顯示。對不起,我的問題沒有說清楚。我要更新它。 – 2012-01-15 22:26:59

2

對於沒有看到代碼的算法不太清楚,但是當您更新ETA時,只需首先檢查當前的ETA,並且只在新值低於舊值時更新它。

+1

我通過[ETACalculator.cs](https://github.com/scottrippey/Progression/blob/master/Progression/Extras/ETACalculator.cs ),如果你有興趣。然而,在我的情況下,進展可能會放緩,在這種情況下,我想展示一個準確的ETA。 – 2012-01-15 21:55:28