我正在练习Skiena关于算法的书,我坚持这个问题:
我需要计算以下算法的大O:
function mystery()
r=0
for i=1 to n-1 do
for j=i+1 to n do
for k=1 to j do
r=r+1
这里,最外层循环的大O为O(n-1),中间循环为O(n!)。如果我错了,请告诉我。
我无法计算最里面循环的大O.
有人可以帮我解决这个问题吗?
答案 0 :(得分:2)
分析如下:
i = [1, n - 1]
,因此如果在此循环内仅执行常量操作,则程序将具有线性复杂度O(i) = O(n)
; i
,某些操作执行n
次 - 从j = [i + 1, n - 1]
开始。这使得总复杂度为O(i * j) = O(n * n) = O(n^2)
; i
以及每j
,k
次执行最内层循环,k
范围为k = [j, n - 1]
。由于j
以i + 1 = 1 + 1
开头,k
渐近等于n
,后者为O(i * j * k) = O(n * n * n) = O(n^3)
。程序本身的复杂性对应于最内层操作的迭代次数 - 或者最内层操作的复杂性总和。如果你有:
for i = 1:n
for j = 1:n
--> innermost operation (executed n^2 times)
for k = 1:n
--> innermost operation (executed n^3 times)
endfor
for l = 1:n
--> innermost operation (executed n^3 times)
endfor
endfor
endfor
总复杂度将以O(n^2) + O(n^3) + O(n^3)
为单位,等于max(O(n^2), O(n^3), O(n^3))
或O(n^3)
。
答案 1 :(得分:2)
这是解决此问题的更严格方法:
将算法的运行时定义为f(n)
,因为n
是我们唯一的输入。外循环告诉我们这个
f(n) = Sum(g(i,n), 1, n-1)
其中Sum(expression, min, max)
是从expression
到i = min
的{{1}}的总和。请注意,在这种情况下,表达式是i = max
的评估,其中包含固定的g(i, n)
(求和索引)和i
(n
的输入)。我们可以剥离另一层并定义f(n)
:
g(i, n)
这是g(i, n) = Sum(h(j), i+1, n), where i < n
h(j)
范围j
到i+1
的总和。最后我们可以定义
n
因为我们假设h(j) = Sum(O(1), 1, j)
需要时间r = r+1
。
此时请注意,我们还没有做过任何挥手,说“哦,你可以将这些循环加在一起。”'最里面的操作'是唯一重要的操作。“对于所有算法,该语句甚至不是 true 。这是一个例子:
O(1)
上述算法不是for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
Solve_An_NP_Complete_Problem(n);
for (k = 0; k < n; k++)
{
count++;
}
}
}
......它甚至不是多项式。
无论如何,既然我已经建立了严格评估的优越性(:D),我们需要向上工作,这样我们才能找出O(n^3)
的上限。首先,很容易看出f(n)
是h(j)
(只使用Big-Oh的定义)。由此我们现在可以将O(j)
重写为:
g(i, n)
因此我们可以将g(i, n) = Sum(O(j), i+1, n)
=> g(i, n) = O(i+1) + O(i+2) + ... O(n-1) + O(n)
=> g(i, n) = O(n^2 - i^2 - 2i - 1) (because we can sum Big-Oh functions
in this way using lemmas based on
the definition of Big-Oh)
=> g(i, n) = O(n^2) (because g(i, n) is only defined for i < n. Also, note
that before this step we had a Theta bound, which is
stronger!)
重写为:
f(n)
您可以考虑证明下限以显示f(n) = Sum(O(n^2), 1, n-1)
=> f(n) = (n-1)*O(n^2)
=> f(n) = O(n^3)
。这里的技巧是简化f(n) = Theta(n^3)
但在计算g(i, n) = O(n^2)
时保持紧密限制。它需要一些丑陋的代数,但我很确定(即我实际上并没有这样做)你也可以直接证明f(n)
(如果你真的那么直接f(n) = Omega(n^3)
细致)。
答案 2 :(得分:1)
它不能是阶乘的。例如,如果你有两个嵌套循环,那么大的O将是n ^ 2,而不是n ^ n。所以三个周期不能超过n ^ 3。继续挖掘;)