【问题标题】:About Big O Notations and Complexity关于大 O 符号和复杂性
【发布时间】:2014-11-13 03:19:18
【问题描述】:

我目前正在学习 Big O 表示法,但我对根据不同复杂性计算时间/迭代次数感到有点困惑。

这个问题是我自己编的:

遍历所有可能解决方案的算法每次测试需要 10^(-7) 秒。 如果解数是以下函数:logn,n,nlog。 n^2,我能计算出的最大n是多少,比如不到1秒?

我认为(对于 logn 案例)是 10^-7 次 logn 必须花费不到 1 秒:

10^(-7) * logn < 1 <=> n = 10^(1/10^-7)

难以置信的大(如果没记错的话,哦该死的--')。但是 n^2 呢?

10^(-7) * n^2 < 1 <=> n = square_root(1/10^-7)

但是,如果复杂度更大,n^2 情况下的解决方案数量怎么会小于 n 中的数量呢?这让我很困惑……?

【问题讨论】:

  • 应该注意的是,对于编程,log N 几乎总是以 2 为底,而不是 10 为底,除非指明不同的底,否则应真正如此对待。

标签: algorithm big-o


【解决方案1】:

“这在很多层面上都很糟糕。”

首先,O(f(n)) 与 f(n) 不同。

复杂度通常用于表示解决问题所需的时间,它是输入的大小的函数。

当然如果你可以在相同的时间内用 X 和 Y 解决更多的问题,那么 X 将在固定的时间内解决比 Y 更多的问题。但是由于你没有使用以正确的方式使用术语复杂性,您会得到一个(看似)自相矛盾的答案也就不足为奇了。

【讨论】:

  • 重新表述了问题。
【解决方案2】:

您刚刚将算法上限设置为 10^(-7) 秒的真实世界时间,这意味着您的算法将保证在 10^(-7) 秒内完成所有复杂性。

让我们不要讨论这在现实中是否可能。但是由于您刚刚定义了算法以在 10^(-7) 中遍历所有可能的解决方案,这意味着无论 n 是多少,它都会在那个时间内完成。所以你的 n 是正无穷大。

此外,我认为您不应该使用大 O 来表示解决方案的数量

【讨论】:

    【解决方案3】:

    好消息首先,您的计算结果没有“错误”。

    当然,如果算法的复杂度更高(例如 O(n^2) 复杂度高于 O(log n)),那么您仍然能够在“可接受”时间内处理的问题规模会更小,完全按照你的计算。

    尽管这个例子似乎有点扭曲,我不得不承认,我没有完全理解目的,你发明了 10^-7 因子,因此怀疑你没有正确理解 O 符号的概念.

    本质上,O 表示法的主要思想是,在比较两种算法时,您不关心任何线性因子(例如您在计算中发明的 10^7 因子),而只关心计算时间的增长速度问题的规模,因为与问题规模导致的计算时间增长相比,常数(因此不会增长)因素迟早会变得无关紧要。

    举个例子:

    使用 O(n^2) 算法 A,耗时 t=2*n^2 毫秒,使用 O(log n) 算法 B,在特定机器上耗时 t=200*log(n) 毫秒给定问题大小 nr 的情况如下所示:

    对于一个非常小的问题,比如 n=10,算法 A 可能比算法 B 更快:

    2*10^2 = 2*100 = 200 毫秒 400*log10 = 400*1 = 400 毫秒

    但是随着问题规模的扩大,比如 n=100,算法 B 迟早会在速度上超过算法 A:

    2*100^2 = 2*10,000 = 20,000 毫秒 400*log100 = 400*2 = 800 毫秒

    对于更大的问题,比如 n=1,000,000,等待 A 完成可能需要很大的耐心。

    2*1,000,000^2 = 2*10^12 毫秒 = 2*10^9 秒 = 33333333 分钟 = 555555 小时 = 23148 天 = 63 年

    算法 B 可能仍会在可接受的时间内运行。

    400*log1,000,000 = 400*6 = 2,400 毫秒 = 2.4 秒

    随着问题规模的增长,常数因子扮演的角色越来越小,对于越来越大的问题,它变得越来越无关紧要,因此(连同遵循相同规则的低阶项)在 O符号。

    因此,查看 O 表示法中给出的复杂性的“正确”方法不是尝试查看固定 n 的固定值,甚至不重新发明常数因子和已经抽象出的低阶附加项,而是查看计算时间有多快随着问题的大小而增长。

    因此,再次以示例为例,查看 O(n^2) 和 O(log10) 复杂性的“正确”方法是比较它们的增长。

    如果问题大小增加 10 倍,算法 A 的计算时间将增加 100 倍,因此需要的时间是以前的 100 倍,如下所示:

    (n*10)^2 = n^2 * 10^2 = n^2 * 100

    虽然算法 B 的计算时间只会增长一个常数,如下:

    对数(n*10)=对数(n)+对数(10)=对数(n)+1

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-12
      • 2020-08-17
      • 1970-01-01
      • 2017-09-28
      • 2011-09-05
      相关资源
      最近更新 更多