根据样本运行估算模拟运行时间

时间:2012-06-21 05:41:03

标签: algorithm time-complexity timing

我需要在周末进行模拟。我希望模拟足够大,以尽可能具有描述性,但我不希望它在我恢复工作时没有完成,我无法继续使用该软件。

算法是这样的,一旦启动,它必须完成或根本没有运行它的点。

模拟的各个元素以阶乘,n ^ 4和n ^ 2

运行
   n:
<= 6  =         0ms
   7  =         8ms
   8  =        91ms
   9  =     1,089ms
   10 =    14,666ms
   11 =   197,288ms
   12 = 3,091,739ms

我在WolframAlpha here中对这些样本拟合曲线。与我有关的两件事首先是n ^ 4分量是负的,这没有任何意义,因为它肯定是运行时的一个因素。另一件事是,我曾尝试在类似的情况下估计过去的运行时间,而且我的推断通常都是偏离的。

您是否有过以这种方式根据输入大小猜测算法运行时的经验?

2 个答案:

答案 0 :(得分:1)

为什么外推失败:
当你想要估算一个超出原始范围的值时,预计推断是偏离的。
在多项式外推中至少 - error是点到所有采样点之间距离与该范围内函数的n'导数的最大值的乘积的函数。如果这个距离很大 - 它(距离和最大导数的乘积)预计会很高。

n ^ 4分量给出负值,因为它显示了可以解释“观察”的最佳函数。

为了估算样品区的运行时间 - 我建议避免使用外推法。当走出已知样品的“舒适区”时,它们的定义并不是很好。

考虑替代方案: 我试着找到常数的粗略估计(通过静态分析代码) - 主要是 - 我想看看阶乘分量是否具有非常小的常数,其余部分具有非常大的常数。如果不是这样的话,可以忽略n ^ 2和n ^ 4个组件 - 与因子组件相比,它们可以忽略不计,这将更容易分析。

PS 从查看提供的动态数据 - 似乎是这种情况,运行时间之间的差异很快会收敛到阶乘因子,因此将函数分析为阶乘,并估算{{ 1}}等似乎是一个合理的假设。
如果您想要安全起见,可以使用f(12) ~= 12* f(11),其中d是预定义的正常数,例如f(n) = (n + d) * f(n-1)

<强> P.S.2: 由于阶乘的行为是如此激进,你可以尝试迭代地运行模拟,d = max{0,f(11)/f(10) - 11}对于任何f(1) + f(2) + ... + f(n)预计不会比f(n)花费更长的时间。通过这样做,您将得到您有时间计算的结果,尽管您在回到办公室时会中止它。此行为称为any time

答案 1 :(得分:1)

一般来说,当你有一些O(N 4 )时,你也必须引入O(N 3 ),O(N 2 < / sup>),O(N)和O(1)。换句话说,尝试将x 3 ,x 1 和x 0 添加到曲线拟合模型中。

对于这个特殊情况,你有一个O(N!),好吧,我会遵循amit建议,只考虑阶乘部分,因为它似乎收敛得非常快。

但无论如何,如果你真的有一个O(N!),你不需要估计,只需使用iterative deepening方法。让你的计算机迭代运行n = 1,2,3,4,5,6,7的情况...并尽可能地让它去。

似乎你在浪费你的计算机时间,但如果你分析它,你会发现浪费的时间是微不足道的。例如,你已经在n = 12,所以对于n = 13,所需的CPU C 13 将是13 * C 12 ,C 12 = 12 * C 11 ,依此类推。引入您的测量值,总和(C 13 .. C 0 )/ C 13 = 1.082,因此为0中的所有值运行函数13只比仅运行13只贵8%。当你想要更大的N值时,这个百分比会进一步缓解。

<强>更新

为什么您需要为复杂程度以下的所有权力添加条款:

考虑一个复杂度为O(N 3 )的简单三级循环:

void foo(int n) {
  int i, j, k;
  for (i = 0; i < n; i++)
    for (j = 0; j < n; j++)
      for (k = 0; k < n; k++)
        do_something(i, j, k);
}

foo(3);

很明显,do_something(i, j, k)被称为n 3 次。

但是我们从开始考虑每个执行的指令,我们可以看到进入和离开函数,设置堆栈和其他低级别任务一次完成; i=0指令也执行一次。这些是与n 0 成本相对应的指令。

说明i < ni++j=0被称为n次,它们对应于n 1 术语。

指令j < nj++k=0称为n 2 次,它们对应于n 2 项。

好吧,等等。

更复杂的情况是相同的,你总是有指令运行的次数与复杂程度以下的所有权力成比例。

关于C(0) = 0的测量,这只是你的时间不够准确的问题。它可能非常小但绝不是绝对的0。

最后,如果你的曲线拟合不起作用,那是因为N!在这种情况下你也会有运行指令(n-1)!时间和(n-2!)次等等。