【问题标题】:Calculate the complexity of the function, hw in python计算函数的复杂度,python中的hw
【发布时间】:2013-12-07 14:12:23
【问题描述】:

我需要根据 n 计算函数的运行时间复杂度(例如 O(n)), n 是 len(lst) ,lst 是列表类型的变量。

这就是我的想法,对吗? (我需要找到最紧密的界限!!!)

【问题讨论】:

  • 别人有同样的作业:stackoverflow.com/questions/20425922/…
  • 我猜应该是更接近O(n^2)的东西,不知道那些2i*2i是从哪里来的。
  • 我不确定最里面的循环。它实际上是恒定的时间,因为它永远不会执行超过 20,000 次吗?
  • @Tim:也是这么想的。但不是恒定时间:如果 i
  • 我认为它是恒定的,因为最终它是由一个常数限制的

标签: python function loops python-3.x time-complexity


【解决方案1】:

好的,这是一个相当复杂的问题,对于家庭作业来说非常有趣。

首先很明显,您必须将问题分成两部分,无论 n 是否大于 100 000。

如果 n 大于 100 000:

您将一次运行最里面的循环最多 20 000 次(因为当 j 大于 100 000 时,您的 k 循环将导致 0 次迭代)。 因此,对于每次模拟,对于 n 高于 50 000 的部分,您将准确执行

总循环。它给了

。你要加上i

,

这给了。

这意味着在 n = 100 000 以上,您的问题具有明显的 O(n) 复杂性,其中恒定部分比线性部分小一个或多个数量级:

当你低于 n = 100 000 时,棘手的部分就到了。你可以在这里写

,

可以转化为:

此函数显示线性增加和平方减少。猜猜它的根在哪里……(几乎)正好是 100 000。

计算总和并留下你得到的 O(1)、O(n) 和非重要部分:

.

你可以看到它的立方部分是负数,所以对于大的 n-s,时间会低于 0。但是你也可以看到,在 n = 100 000 时,平方部分仍然是三次方的 3 倍,并且函数的最大值在 n = 200 000 时。所以不用担心,你不会进入负数,其实你连这个函数的最大值都达不到。

你怎么解释这个?好吧,在最坏的情况下,您的复杂度为 O(n2)。但是你有一个更高阶的下降,并且对于低于 100 000 的大 n-s,你可以做得比 O(n2) 预测的要好得多(最多 33%)。

总结一下:

  • 如果 n 远小于 100 000:O(n2)
  • 如果 n 接近,但小于 100 000:略好于 O(n2)
  • 如果 n 大于 100 000:O(n)

我运行了一个示例来衡量发生了什么。我使用了不同的数字(因为您的原始问题将永远运行),因此在我的情况下,您的 100 000 阈值为 100。你可以看到,一开始,O(n2) 工作得很好,然后 O(n2-n3) 很好地适应了复杂度,最后,在 100 以上,我们进入了线性部分。

对于较大的 n-s(阈值仍然为 100):

【讨论】:

  • 我不相信这是正确的。高于阈值,k 循环在恒定时间内完成,而ij 循环的顺序为 n。对于较大的 n 值,整体函数为 O(n^2)。低于阈值的所有循环都是 n 阶的,使得函数 O(n^3)。我用 100 的阈值对 n 的大值进行了计时,它显然不是线性的。 i.imgur.com/i1Fglwc.png
  • @Tim:不仅是 k,而且 j 循环在 n > 10^5 的恒定时间内完成!因为只有 j in range(10^5) 部分会给你任何东西(这是一个常数),而 range(10^5,n) 中的 j 什么也不做!我无法重现您的结果,我得到的线性依赖性高达 10000,阈值为 100(请参阅编辑后的答案)。另一方面,请注意您的 n^3 部分正在下降,因为在内部循环中,大 j-s 会运行得快,而小 j-s 会运行得慢!所以你有一个O(n3)的依赖,但是它是负数,前导部分只有O(n2)。
  • for j in range(i) 将线性缩放 - 它不会在恒定时间内完成。听起来您对提问者使用了不同的代码。
  • @Tim:我仍然不同意,但您绝对有可能是对的。你应该把你的解决方案写成对 OP 的回答,我会尽力理解它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
  • 2015-07-25
  • 2015-09-26
  • 1970-01-01
相关资源
最近更新 更多