Algorithm 基于样本运行估计仿真运行时间

Algorithm 基于样本运行估计仿真运行时间,algorithm,time-complexity,timing,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,0

我需要在周末进行模拟。我希望模拟足够大,它将尽可能具有描述性,但我不希望它在我回去工作时没有完成,我不能继续使用这个软件

算法是这样的,一旦启动,它必须完成,否则运行它就毫无意义

模拟的各个元素按阶乘n^4和n^2运行

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

外推失败的原因:
当您希望估计超出原始范围的值时,外推可能会有很大的偏差。
在多项式外推中,至少-是点到所有采样点之间的距离与该函数在该范围内的n阶导数的最大值的乘积的函数。如果该距离较大,则该距离(距离与最大导数的乘积)预计较高

n^4分量给出的是负值,因为它显示了能够解释“观测”的最佳函数

对于估计样本区域的运行时间,我建议避免使用外推。从定义上讲,它们不是很好的估计,因为它们超出了已知样本的“舒适区”

考虑另一种选择:
我试图找到常数的粗略估计(通过静态分析代码)——主要是——我想看看阶乘分量是否有非常小的常数,其余的是否有非常大的常数。如果情况并非如此,则可以忽略n^2和n^4分量-与阶乘分量相比,它们是可忽略的,这将更易于分析

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

p.S.2:

由于阶乘的行为非常激进,您可以尝试迭代运行模拟,
f(1)+f(2)+…+对于任何
n>10
,f(n)
预计不会比
f(n)
花费更长的时间。通过这样做,您将得到您有时间计算的结果,尽管您返回办公室时会中止计算。这种行为被称为。

一般来说,当你有一些O(N4)时,你还必须引入O(N3)、O(N2)、O(N)和O(1)的术语。换句话说,尝试将x3、x1和x0添加到曲线拟合模型中

对于这个特殊的情况,如果你有一个O(n),那么,我会遵循AMIT建议,只考虑阶乘部分,因为它似乎收敛得很快。

但在任何情况下,如果你真的有一个O(N!),你不需要估计,只需要使用一种方法。让您的计算机迭代运行n=1,2,3,4,5,6,7的情况。。。尽可能让它走得更远

看起来你在浪费你的电脑时间,但是如果你分析一下,你会发现浪费的时间是微不足道的。例如,您已经处于n=12,因此对于n=13,所需的CPU C13将是13*C12,C12=12*C11,依此类推。在介绍您的测量值时,sum(C13..C0)/C13=1.082,因此为0到13之间的所有值运行函数的成本仅比仅为13运行函数的成本高8%。当你选择更大的N值时,这个百分比会进一步降低

更新

为什么需要为复杂性级别以下的所有权限添加术语:

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

void foo(int n){
int i,j,k;
对于(i=0;i
显然,
do_something(i,j,k)
被称为n3次

但是如果我们从一开始就考虑执行的每一条指令,我们可以看到比进入和离开函数、设置堆栈和其他低级任务都要完成一次;
i=0
指令也执行一次。这些是与n0成本相对应的说明

指令
i
i++
j=0
被称为n次,它们对应于n1项

指令
j
j++
k=0
称为n2次,它们对应于n2项

嗯,等等

更复杂的情况是相同的,您总是有指令运行次数与低于复杂度级别的所有幂成比例

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


最后,如果曲线拟合不起作用,那是因为N!在这种情况下,您还将运行指令(n-1)!次数,和(n-2!)次等等。

当使用f(n)=nf(n-1)时,我发现错误为1.3。做f(n)=1.3*nf(n-1)似乎能给出相当准确的结果。我还更新了我的问题,显示n=12,刚刚完成。这是非常糟糕的结果-我可以运行模拟约15小时或约9天。两者之间什么都没有!:(@user1002358:这是处理阶乘时通常发生的情况……合理时间和“直到地球爆炸才会结束”之间的差异只是几个数字。希望我的回答能帮助你,至少能理解为什么外推通常不适用于这些情况:\@user1002358:看看我上次的编辑,你可以尝试迭代运行模拟:大小1,大小2,大小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);