English 中文(简体)
算法的复杂性
原标题:
  • 时间:2009-02-03 18:32:07
  •  标签:

我有一个相当普遍的问题。除了在学校当程序员之外,你是否曾经不得不真正计算(例如在纸上)算法的复杂度?如果可以,请举个例子。

谢谢 :)

问题回答

如果你正在编写一段软件并且可以想到多种实现方法,通常一个决定性的因素(除了概念复杂度和实现时间)将会是算法复杂度。因此,当你的老板要求你解释你的决定时,弄清楚每个实现方式的复杂度是必要的。虽然有些人可能认为这是一种过早的优化,但我认为共识是选择适合你的问题的设计只是好的软件工程实践。

完全没错-我们最近刚刚遇到了我们的应用程序出现了一些重大减速的问题。原来我们在一个非常重要的函数中间有一个立方体(O(n^3))算法。它被隐藏在多重抽象层之下。弄清楚发生了什么需要绘制函数调用图并查看详细信息。

诚然,一旦我们完成了这个,我并不需要应用任何数学知识来注意到一个O(n^3)的算法,但这主要是因为我在大学三年的算法分析课上对立方算法的一般感觉。

无论如何,事实证明N只增加了一点点,但它正处于从几百毫秒到几秒钟再到几分钟的临界点上 - 所以这个问题直到最近才出现。

大多数情况下,您将使用已定义复杂性的预打包算法。 快速排序的最坏情况为O(n ^ 2),平均情况为O(n * log(n)),二分查找为O(log(n)),等等。 库通常会指定它们的性能特征,您只需要担心它们的组合方式即可。

在工作中,我们随意讨论不同的算法来解决问题,而且复杂度也很重要。我们从来不需要做复杂度的严格证明,只是一个普通的说法:"我们可以做X,但是这将是O(N^2),因为我们可能要遍历数百万行,那样太复杂了。"

过度优化会导致不良代码,但了解基本算法的复杂性可以帮助确定解决编程问题的最佳方法。

我不知道你是否把编程竞赛看作是学校的一部分,但要想在时间限制内解决竞赛问题(满足指定问题规模限制),你必须考虑所使用算法的复杂性,大致估算操作的数量。

当然了!随时可以。如果你要重复执行一百万次,你可能需要检查一下你的算法了。

我曾经做过的一个实例是生成数百万张需要适配于网格模式的图像。抱歉,这个实例无法提供更多详细信息。

是。

通常情况下,复杂性对于餐巾纸猜测来说已经足够明显了,这对开发来说是可以接受的,直到我需要衡量性能的地步。在许多情况下,我担心的部分是好的(即餐巾纸猜测已经足够好了),而其他东西正在减慢软件。在几乎所有情况下,跟随我的基本假设并稍后进行性能测量是值得的。

然而,当我在进行非常时间关键的代码时,尤其是在图形渲染方面,我会坐下来确定算法复杂度并权衡采用其他方式进行时的取舍。

今天我在和别人的代码一起工作,它非常慢。 我并不是很在意 - 它可以花费10分钟,对于它增强的整个过程而言并不重要。 但是,我必须查看代码以修复错误,而这个人的代码中有嵌套的循环,大多数循环以相同的方式搜索同一列表以获取不同的元素。 实质上,他已经将一个很好的数组函数,比如func(i){return records [i];}变成了一个可怕的搜索例程:

func(i)
{
   for each index in records
      if i==index return records[index]
   next
}

现实情况要严重得多,但你能明白我的意思。

你现在在学校学习这个的原因是为了让你看到这些结构并自动分类它们。 你可能不需要实际计算或将它简化为一个漂亮的复杂度数字,但如果你现在不亲自做并看到很多,你也会编写像那样的代码,而你将完全没有头绪。

亚当

我不知道我实际上有没有写下东西,但我一直在评估我构建算法的方式,看看是否可以提高其效率。 对于代码,我会问自己是否有一种方法可以将嵌套循环转换为单个循环或从循环转换为使用分而治之的方法。 这将等价于从O(N ^ 2)到O(N)和从O(N)到O(log 2 N)。 SQL也是如此-我能否删除连接并使用索引进行子查询-也许从O(N ^ 2)到O(N)(甚至是O(1)如果它使我能够在两个表上进行索引查询)。

是和不是。

我正在编写一种工具,将一组软件包的RPM依赖关系压缩成单一链。显然的解决方案运行速度太慢了,所以我翻阅了一下我的记忆,想起了图论课上的一个O(n+m)算法。我做了一些草稿计算,确保它确实是一个O(n+m)算法,然后将它写入生产 :)





相关问题
热门标签