15

tl; dr:我想预测文件复制完成。考虑到开始时间和当前进度,有哪些好的方法?

首先,我知道这根本不是一个简单的问题,预测未来很难做好。对于上下文,我试图预测一个长文件复制的完成。

当前方法:

目前,我正在使用我自己提出的一个相当幼稚的公式:(ETC 代表预计​​完成时间)

ETC = currTime + elapsedTime * (totalSize - sizeDone) / sizeDone

这是假设要复制的剩余文件将以迄今为止的平均复制速度进行复制,这可能是也可能不是一个现实的假设(此处处理磁带存档)。

  • PRO: ETC 会逐渐变化,并且随着过程接近完成而变得越来越准确。
  • 缺点:它对意外事件反应不佳,例如文件副本卡住或加速过快。

另一个想法:

我的下一个想法是记录最后n秒(或几分钟,因为这些档案应该需要几个小时)的进度,然后执行以下操作:

ETC = currTime + currAvg * (totalSize - sizeDone)

这与第一种方法相反:

  • PRO:如果速度变化很快,ETC 将快速更新以反映当前的事务状态。
  • CON:如果速度不一致,ETC 可能会跳动很多。

最后

我想起了我在 uni 学过的控制工程科目,其目标本质上是试图让系统对突然的变化做出快速反应,但又不会不稳定和疯狂。

话虽如此,我能想到的另一个选择是计算上述两者的平均值,也许有某种加权:

  • 如果副本具有相当一致的长期平均速度,则对第一种方法的权重更大,即使它在局部跳跃一点。
  • 如果复制速度不可预测,并且可能会长时间加速/减速或长时间完全停止等操作,则更加重视第二种方法。

我真正要求的是:

  • 我给出的两种方法的任何替代方法。
  • 如果以及如何结合几种不同的方法来获得最终预测。
4

4 回答 4

8

如果您觉得预测的准确性很重要,那么构建预测模型的方法如下:

  1. 收集一些真实世界的测量值;
  2. 将它们分成三个不相交的集合:训练验证测试
  3. 想出一些预测模型(你已经有两个加上一个混合)并使用训练集来拟合它们;
  4. 检查验证集上模型的预测性能,并选择表现最佳的模型;
  5. 使用测试集来评估所选模型的样本外预测误差。

我冒险猜测您当前模型和“过去n秒内的平均值”的线性组合对于手头的问题会表现得很好。可以使用线性回归R中的单线)拟合线性组合的最佳权重。

学习统计学习方法的一个极好的资源是Hastie、Tibshirani 和 Friedman的 The Elements of Statistical Learning。我不能高度推荐这本书。

最后,您的第二个想法(过去n秒的平均值)尝试测量瞬时速度。一种更强大的技术可能是使用卡尔曼滤波器,其目的正是如此:

其目的是使用随时间观察到的、包含噪声(随机变化)和其他不准确的测量值,并产生更接近测量值的真实值及其相关计算值的值。

使用卡尔曼滤波器而不是固定的n秒滑动窗口的主要优点是它是自适应的:当测量值跳动很多时,它会自动使用更长的平均窗口,而不是当它们稳定时。

于 2011-10-06T07:26:18.337 回答
4

恕我直言,ETC 的糟糕实现被过度使用,这让我们笑得很开心。有时,显示事实而不是估计可能会更好,例如:

  • 已复制 10 个文件中的 5 个
  • 已复制 200 MB 中的 10 个

或者展示事实估计,并明确表示这只是一个估计。但我不会只显示一个估计值。

每个用户都知道 ETC 通常是完全无意义的,然后很难区分有意义的 ETC 和无意义的 ETC,尤其是对于没有经验的用户。

于 2011-10-06T07:42:19.590 回答
3

这里有两点需要考虑:

  • 准确的估计
  • 如何呈现给用户

1.关于估计

除了统计方法之外,在消除一些噪声或尖峰的同时对当前速度进行良好估计的一种简单方法是采用加权方法。

您已经对滑动窗口进行了实验,这里的想法是采用一个相当大的滑动窗口,但不是一个普通的平均值,而是给最近的测量更多的权重,因为它们更能指示进化(有点像衍生物) .

示例:假设您有 10 个以前的窗口(最近的 x0,最近的 x9),那么您可以计算速度:

Speed = (10 * x0 + 9 * x1 + 8 * x2 + ... + x9) / (10 * window-time) / 55

当你对可能的速度有一个很好的评估时,你就可以得到一个很好的估计时间。

2. 介绍

这里要记住的主要事情是你想要一个好的用户体验,而不是一个科学的前沿。

研究表明,用户对减速的反应非常糟糕,而对加速的反应非常积极。因此,一个好的进度条/估计时间首先应该在所呈现的估计中保守(为潜在的减速保留时间)。

一个简单的方法是使用一个完成百分比的因子,您可以使用它来调整估计的剩余时间。例如:

real-completion = 0.4
presented-completion = real-completion * factor(real-completion)

哪里factor是这样的factor([0..1]) = [0..1]factor(x) <= xfactor(1) = 1。例如,三次函数对完成时间产生了很好的加速。其他函数可以使用指数形式1 - e^x等...

于 2011-10-06T12:13:23.933 回答
3

我已经实施了两种不同的解决方案来解决这个问题:

  1. 开始时当前传输的 ETC 基于历史速度值。此值在每次传输后进行细化。在传输过程中,我计算了历史数据和当前传输数据之间的加权平均值,这样越接近最后,传输的实际数据的权重就越大。

  2. 与其显示单个 ETC,不如显示一个时间范围。这个想法是从最后'n'秒或分钟计算ETC(就像你的第二个想法)。我跟踪最好和最坏情况的平均值,并计算一系列可能的 ETC。这在 GUI 中显示有点令人困惑,但可以在命令行应用程序中显示。

于 2011-10-06T07:39:51.007 回答