为什么O(2n ^ 2)和O(100 n ^ 2)在算法复杂度上与O(n ^ 2)相同?

时间:2013-09-02 11:45:34

标签: algorithm complexity-theory asymptotic-complexity

我是算法分析领域的新手。我在Stack Overflow问题中读到这里 “What is a plain English explanation of "Big O" notation?O(2n^2)O(100 n^2)O(n^2)相同。我不明白这一点,因为如果我们采用n = 4,操作次数将为:

  • O(2 n^2) = 32次操作
  • O(100 n^2) = 1600次操作
  • O(n^2) = 16次操作

任何人都可以解释为什么我们应该将这些不同的操作计数视为等效吗?

3 个答案:

答案 0 :(得分:9)

为什么这是真的可以直接从the formal definition导出。更具体地说,f(x) = O(g(n))当且仅当|f(x)| <= M|g(x)| for all x >= x0用于某些Mx0。在这里,您可以根据需要随意选择M,因此如果M = 5 f(x) = O(n2)为真,那么您只需选择M = 5*100 f(x) = O(100 n2)即可是的。

为什么这很有用是一个不同的故事。

关于使常数很重要的一些问题:

  • 我们测量的是哪些操作?数组访问?算术运算?仅乘法?算术乘法加权加倍加法?您可能希望使用此度量标准来比较算法(具有相同的Big-O复杂度),实际上即使是最有经验的计算机科学家也可能会错过的操作数量会有一些微妙的差异。
  • 假设您可以为每个操作分配合理的权重。现在必须有一个全面的协议,否则你会对使用不同权重的人所做的算法进行一些近乎无意义的分析(除了大O给你的信息)。
  • 权重可能有时间限制,因为操作速度会随着时间的推移而提高,而某些操作可能会比其他操作更快地提高。
  • 权重可能受环境限制,因为不同环境下的操作速度可能不同。例如,磁盘读取比读取内存慢很多。

Big-O(渐近复杂度的一部分)避免了所有这些问题。您只需检查执行一段时间(即独立于输入大小)的某段代码的次数。例如:

c = 0
for i = 1 to n
for j = 1 to n
for k = 1 to n
  x = input[i]*input[j]
  y = input[j]*input[k]
  z = input[i]*input[k]
  c += (x-y)*z

所以有4次乘法,1次减法和1次加法,每次执行n 3 次,但这里我们只说这段代码:

  x = input[i]*input[j]
  y = input[j]*input[k]
  z = input[i]*input[k]
  c += (x-y)*z

以恒定时间运行(无论数组中有多少元素,它总是需要相同的时间)并且将执行O(n3)次,因此运行时间为O(n3)

答案 1 :(得分:3)

因为O(f(n))表示所述函数以某种常数次f(n)。如果g100 f(n)的多个限制,则它也会被f(n)的倍数包围。具体来说,O(2 n^2)并不意味着n = 4不超过16,但对于所有 n而言,对于某些已修复的<{1}}并不大于C * 2n^2 C,独立于n

答案 2 :(得分:1)

因为它是一个分类,所以它将算法放在一些复杂性类中。类是O(1),O(n),O(n log n),O(n ^ 2),O(n ^ 3),O(n ^ n)等。根据定义,两个算法在当n变为无穷大时,如果差值是一个常数因子,那么相同的复杂度类别(大的符号用于比较大的n值的算法复杂度)。