我需要在周末进行模拟.我希望模拟足够大,以尽可能具有描述性,但我不希望它在我恢复工作时没有完成,我不能继续使用这个软件.
该算法一旦启动,它必须完成或根本没有运行它的点.
模拟的各个元素以阶乘,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分量是负的,这没有任何意义,因为它肯定是运行时的一个因素.另一件事是,我曾尝试在类似的情况下估计过去的运行时间,而我的推断通常是偏离的.
你们有没有经验以这种方式根据输入大小猜测算法的运行时间?
最佳答案 通常,当你有一些O(N4)时,你也必须引入O(N3),O(N2),O(N)和O(1)的术语.换句话说,尝试将x3,x1和x0添加到曲线拟合模型中.
对于这个特殊情况,你有一个O(N!),好吧,我会遵循amit建议,只考虑因子部分,因为它似乎收敛得相当快.
但无论如何,如果你真的有一个O(N!),你不需要估计,只需使用iterative deepening方法.让你的计算机迭代运行n = 1,2,3,4,5,6,7的情况……让它尽可能地去.
你似乎在浪费你的计算机时间,但如果你分析它,你会发现浪费的时间是微不足道的.例如,您已经在n = 12,因此对于n = 13,所需的CPU C13将是13 * C12,C12 = 12 * C11,依此类推.介绍你的测量值,总和(C13..C0)/ C13 = 1.082,所以运行你的函数从0到13的所有值将比仅运行它的价格贵8%.并且当你去更大的值时N,这个百分比将进一步缓解.
更新:
为什么需要为复杂程度以下的所有权限添加术语:
考虑一个复杂度为O(N3)的简单三级循环:
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)被称为n3次.
但是我们从一开始就考虑每个执行的指令,我们可以看到进入和离开函数,设置堆栈和其他低级别任务一次完成; i = 0指令也执行一次.这些是与n0成本相对应的指令.
指令i< n,i和j = 0被称为n次,它们对应于n1项. 说明j< n,j和k = 0被称为n2次,它们对应于n2项. 好吧,等等. 更复杂的情况是相同的,你总是有指令运行的次数与复杂程度以下的所有功率成比例. 关于C(0)= 0的测量,这只是你的时间不够准确的问题.它可能非常小但绝不是绝对的0. 最后,如果你的曲线拟合不起作用,那是因为N!在这种情况下你也会有运行指令(n-1)!时间和(n-2!)次等等.