我知道冒泡排序,插入排序等,但有更有效的排序算法。通过Time Hierarchy Theorem,存在可以在O(n ^ 2)中解决但在O(n ^ r)中对于任何实数r<用于证明的结构不是很自然。什么是问题的一个很好的例子,其最有效的解决方案需要二次时间?
我正在寻找具有以下品质的东西:
小警告 - 输出不应该很大。 (如果你想要给定列表中每对整数的总和,显然需要二次时间来输出它们)。您可以假设它应该是decision problem,即具有是 - 否答案的{{3}}。我们还假设时间复杂度O(n ^ 2)是输入大小的函数,即n是表示输入所需的位数。
答案 0 :(得分:8)
Matrix multiplication具有Ω的理论下界( n 2 ),因为所有 n 2 条目需要处理。迄今为止最着名的算法(根据上面链接的维基百科文章)具有复杂度O( n 2.3727 )。朴素算法具有复杂度 n 3 。
根据维基百科关于Computational complexity of mathematical operations的文章,三角矩阵的反向替换以获得 n 解是O( n 2 )。网上可能有很多其他的例子。
编辑:2014 paper by Michele Borassi, et al.,讨论了一些可以在O( n 2 中解决的决策问题(输出大小O(1)) )任何ε>时间但不在O( n 2- ε )中0.(当然,一如既往,这些结果取决于P≠NP,或者更准确地说,Strong Exponential Time Hypothesis是真的。)
他们的论文带有修改后的k-SAT problem:
输入:
输出: true
如果对所有满足所有子句的变量进行评估,则False
。
请注意,未修改的 k -SAT问题(输入中不包含上面的第三个项目符号)是NP完全的,因此通常会将其视为指数时间问题。但是,这里的输入大小本身就是变量数量的指数。他们表明,通过这种修改,问题总是可以在二次时间内解决(只需尝试所有可能的评估)。更重要的是,他们还表明这是解决问题的任何算法的最小时间复杂度。
有人可能反对这个修改过的 k -SAT问题很自然。然而,他们然后使用它来表明许多其他似乎很自然的问题也不能在O( n 2 )时间内解决。最简单的一个是子集图问题:
输入: X 的集合 X 和 X 的子集 C 。
输出:图形 G =( C , E ),其中,每个 C , C '∈ C ,( C , C ')∈ E 当且仅当 C ⊆ C '。
答案 1 :(得分:1)
你在混合计算模型时犯了一个根本性的错误。
heirarchy定理是关于图灵机的时间,而其他大多数边界都有自己的模型(比如排序的比较模型),或者通常是关于RAM模型的。
所以真正的问题是,你在谈论哪种计算模型?
另外,谈论一个不比O(n ^ 2)(BigOh)差的最佳算法是无稽之谈。 BigOH是一个上限。你可能想要使用Theta。
答案 2 :(得分:1)
这差不多一年之后,但我想我有一个答案:部分订单发现。
考虑对总排序进行排序。你有一系列n个对象(我们假设它们是不同的),以及一个比较操作,它测试两个元素以查看一个是否小于或等于另一个。
您正在尝试发现元素所处的排列。有n个!可能的排列,所以你试图发现一个介于1和n之间的数字!每次比较都会给你一些信息。要发现1到n之间的数字!需要发现log(n!)位。因此,所需的比较次数也是log(n!)位,或:
log(n!)= n log n + o(n log n)=Ω(n log n)位
(所有对数当然都在基数2中。)
你不能比这更好。如果每个查询都提供了一位信息,并且您需要至少发现Ω(n log n)位,那么您需要进行Ω(n log n)次比较。如果你认为自己可以做得更好,可以选择Shannon,Chaitin和Kolmogorov。
但更好的是,即使在最坏的情况下(例如堆排序),也可以知道算法。从这个意义上说,堆排序是渐近最优的。
(注意,如果你有一个返回多个信息位的查询操作,你可以做得更好。例如,如果你能找到一个返回Ω(log n)位的那个,那么你应该能够在Ω(n)时间内排序。有关详细信息,请参阅基数排序。)
此分析适用于各种算法。在n个序列中查找单个事物需要发现1和n之间的数字,这意味着发现log n + O(1)位。如果查询操作返回一位,则需要Ω(log n)个查询来进行搜索。 (有关详细信息,请参阅二进制搜索。)
我想你可以看到我的目标。
现在假设你有n个元素,它们之间有一个部分顺序关系,但你不知道它是什么,想要找出来。但是,你所拥有的是一个查询,它比较两个元素x和y,如果x在部分顺序中小于或等于y,则返回“true”。
有一个明显的算法来发现需要Ω(n ^ 2)时间的偏序:简单地将每个元素与每个其他元素进行比较。
但这是最佳的吗?好吧,查询操作返回一位信息。 n个元素的部分订单数由Sloane's A001035给出。如果我正确读取它,此序列为Ω(2 ^(n ^ 2)),这意味着要发现部分顺序,您需要:
Ω(log 2 ^(n ^ 2))=Ω(n ^ 2)位
也就是说,你不能做得比Ω(n ^ 2)时间好,所以这是一个渐近最优的算法。
“那么”,我听到你问,“我买的是输入的大小是n的事实。但是不是输出的大小 O(n ^ 2),所以它在某种深层技术意义上实际上是一种线性算法?“
嗯......也许吧。我现在没有时间详细介绍细节,但我会回答一个问题。
在普通旧排序的情况下,我们可能会给出n 不同的元素。要区别对待,需要使用n 不同的标签进行标记。存储n个不同的标签意味着存储n个数字,每个数字在1和n之间。这些数字中的每一个都需要log n位来表示它,因此问题的总大小为n log n 位。那么为什么我们不说堆排序在问题的大小上是线性的呢?