不确定这是否是适合此类问题的地方,但现在就这样了。给出以下代码,有多少基本操作,以及每个操作执行了多少次。这个运行时间的最大符号是什么?如果重要的话,这是在MATLAB中。
total = 0;
for i = 1:n
for j = 1:n
total = total + j;
end
end
我的想法是,对于每个n,j = 1:n循环运行一次。在j = 1:n循环内有n次计算。因此对于j = 1:n循环,其n ^ 2。这在i = 1:n循环内运行n次,因此计算的总量为n ^ 3,大O值为O(N ^ 3)。这是对的吗?
答案 0 :(得分:1)
简短的回答是:
O(n^2)
长(简化)答案是:
大" O"是指算法的复杂性(在本例中是您的代码)。你的问题问了多少"执行循环或操作,但是" O"符号给出了算法复杂性的相对概念,因此不是绝对量。这完全是不切实际的,O符号的概念是概括了复杂性的度量,以便算法可以相对于另一个进行比较,而不必过多担心执行了多少分配,循环等。
话虽如此,但有关于如何计算算法复杂性的具体指导原则。一般为:
if then else
操作有一些具体规则,但会让事情变得更复杂,我邀请您阅读一些introduction material on performing algorithm complexity analysis。
另外,要小心," n"不是在你的代码中使用的,它是一个特殊的符号,用于表示"泛型"线性复杂性。
测量算法的复杂性是一种递归操作。你从基本的操作开始,然后转到循环等等。所以,这里有一个详细的(我故意细节太多,所以你知道它是如何工作的,但在实践中你不必进入那个级别细节):
您从第一条指令开始:
O(total = 0;) = O(1)
因为这是一项任务。
然后:
O(total = total + j;) = O(total + j) + O(total = x)
其中x
是total + j
的结果。
= O(1) + O(1)
这些是基本操作,因此它们的复杂度为1。
= O(1)
因为" O"是一个伟大的"伟大的"将任何常量之和视为1的指标。
现在进入循环:
O(
for i = 1:n // O(n)
for j = 1:n // O(n)
total = total + j; // O(1)
end
end
)
=
O(
n * (
n * (
1
)
)
= O(n * n * 1)
= O(n^2)
如果连续有两个循环(对于......;对于......;),复杂度不是O(2n),而是O(n),因为O再次推广。
希望有所帮助:)
答案 1 :(得分:0)
您的分析是在正确的轨道上,但您高估了成本n倍。特别是,请看这里:
在j = 1:n循环内有n次计算。所以对于j = 1:n循环,它的n ^ 2。
你是对的,j = 1:n循环进行n次计算,但循环的每次单独迭代只进行1次计算。由于循环运行n次,所完成的工作是O(n),而不是O(n 2 )。如果你从那时起重复其余的分析,你最终会得到完成的总工作量是Θ(n 2 ),这比你之前的结果更紧密。
作为一个注释 - 你实际上可以非常显着地提高速度。请注意,内部循环将总计增加1 + 2 + 3 + ... + n。我们知道1 + 2 + 3 + ... + n = n(n + 1)/ 2,所以你可以重写代码
total = 0;
for i = 1:n
total = total + n * (n + 1) / 2;
end
但请注意,现在你只需添加n份n *(n + 1)/ 2,所以你可以将其重写为
total = n * n * (n + 1) / 2
并且整个过程需要时间O(1)。