我最近一直在练习分析算法。我觉得我对分析非递归算法非常了解,但我不确定,并且刚刚开始全面理解递归算法。虽然,我还没有对我的方法进行正式检查,以及我一直在做的事情是否正确
要问某人是否可以查看我已经实施和分析的一些算法,看看我的理解是否正确,或者我是否完全关闭,会不会太过分。
这里:
1)
sum = 0;
for (i = 0; i < n; i++){
for (j = 0; j < i*i; j++){
if (j % i == 0) {
for (k = 0; k < j; k++){
sum++;
}
}
}
}
我对这一个的分析是O(n ^ 5),原因是: Sum(i = 0到n)[Sum(j = 0到i ^ 2)[1的和(k = 0到j)]] 评估为: (1/2)(n ^ 5/5 + n ^ 4/2 + n ^ 3/3 - n / 30)+(1/2)(n ^ 3/3 + n ^ 2/2 + n / 6 )+(1/2)(n ^ 3/3 + n ^ 2/2 + n / 6)+ n + 1。 因此它是O(n ^ 5)
这是否正确评估循环的总结?
三重求和。我假设if语句总是会通过更糟糕的案例复杂性。对于最坏情况,这是正确的假设吗?
2)
int tonyblair (int n, int a) {
if (a < 12) {
for (int i = 0; i < n; i++){
System.out.println("*");
}
tonyblair(n-1, a);
} else {
for (int k = 0; k < 3000; k++){
for (int j = 0; j < nk; j++){
System.out.println("#");
}
}
}
}
我对这个算法的分析是O(无穷大),因为if语句中的无限递归,如果它被假定为真,那将是最坏的情况。虽然,对于纯粹的分析,我分析了这是不是真的并且if语句不会运行。然后我得到了O(nk)的复杂性,原因是:
总和(k = 0到3000)[Sum(j = 0到nk)为1] 然后评估为nk(3001)+ 3001.因此是O(nk),其中k由于控制循环的迭代次数而不被丢弃。
答案 0 :(得分:4)
第1名
我无法告诉您如何推导出您的公式。通常在算法中有多个步骤时添加术语,例如预先计算数据然后从数据中查找值。相反,嵌套for循环意味着乘法。此外,最糟糕的情况是这段代码的最佳情况,因为给定n值,sum将在结尾处相同。
为了找到复杂性,我们希望找到内循环的计算次数。如果从1到n,摘要通常很容易解决,所以我稍后会从它们中删除0。如果i为0,则中间循环不会运行,如果j为0,则内循环不会运行。我们可以将代码等效地重写为:
sum = 0;
for (i = 1; i < n; i++)
{
for (j = 1; j < i*i; j++)
{
if (j % i == 0)
{
for (k = 0; k < j; k++)
{
sum++;
}
}
}
}
我可以通过迫使外环从2开始让我的生活更加艰难,但我不会去。外循环现在从1到n-1。中间循环基于i的当前值运行,因此我们需要进行求和:
中间for循环总是进入(i ^ 2 - 1),j只能被i整除,共计(i - 1)次(i,i * 2,i * 3,... ,i *(i-2),i *(i-1))。有了这个,我们得到:
然后中间循环执行j次。我们求和中的j与代码中的j不同。求和中的j表示每次中间循环执行时。每次中间循环执行时,代码中的j将为(i * (number of executions so far)) = i * (the j in the summation)
。因此,我们有:
我们可以将i移动到两个求和之间,因为它是内求和的常量。然后,1到n之和的公式是众所周知的:n*(n+1)/2
。因为我们要去n - 1,所以我们必须减去n。这给出了:
平方和和立方总和的总和也是众所周知的。记住我们在两种情况下只求n-1,我们必须记得分别减去n ^ 3和n ^ 2,我们得到:
这显然是n ^ 4。如果我们一路解决,我们得到:
第2名
对于最后一个,实际上是O(无穷大),如果a&lt; 12因为if语句。好吧,从技术上讲,一切都是O(无穷大),因为Big-O只提供运行时的上限。如果&lt; 12,它也是欧米茄(无限)和theta(无限)。如果只有else运行,那么我们得到i * n的1到2999的总和:
注意从1到2999的总和是一个常数(它的4498500)是非常重要的。无论常数有多大,它仍然是常数,而不依赖于n。我们最终将它从运行时计算中抛弃。有时,当理论上快速算法具有大常数时,它实际上比理论上慢的其他算法慢。我能想到的一个例子是Chazelle's linear time triangulation algorithm。从来没有人实现它。无论如何,我们有4498500 * n。这是theta(n):