分而治之:解决子问题明显快于未分问题是效率的一部分吗?
Posted
技术标签:
【中文标题】分而治之:解决子问题明显快于未分问题是效率的一部分吗?【英文标题】:Divide and conquer: is part of the efficiency that solving the subproblems is significantly faster than the undivided problem? 【发布时间】:2020-07-08 21:05:31 【问题描述】:我正在专门考虑快速排序:每个子问题的大小大约是主问题的一半——是否子问题,包括划分主问题然后重新组合解决的子问题的结果的开销,往往是在不到一半的时间内解决了主要问题?
我知道并行解决子问题也是加快算法速度的一种方式,但大多数关于 QuickSort 的讨论都没有提到并行性。
【问题讨论】:
考虑这一点:1) 大多数快速排序/合并排序实现不并行执行。 2)无论如何,Big-O 保持不变。即使工作量分散,整体工作量也不会减少。 如果并行执行没有时间上的提升?这就是你所说的吗?如果是这样,那怎么可能?我认为您是说整体工作没有减少;但很明显,如果任何事情都可以并行完成,那么速度就会提高,并行性是 D&C 提供的一件事。 整体工作不会因并行性而减少(并且可能会增加)。上墙时间较少,但花费的总时间(能量)是相同的。假设 100% 的工作可以并行化(无论如何都要注意这里的情况),处理 X 个单位实际上与处理 1 个单位的处理速度没有什么不同:这不会影响复杂性界限。 显然在某些情况下速度很重要。 回到最初的思考和第一条评论。这将有助于关注为什么合并排序(比快速排序更容易分析)的时间界限比冒泡排序更好。 Big-O 只是关于极限,因为 N 接近无穷大。对于较小的 N(或者因为它使用更多资源运行),冒泡排序“更快”与边界无关。对于特定的合并排序是否并行化也是如此。 【参考方案1】:不是真的。如果您分析 QuickSort,您会发现它的效率实际上是枢轴质量的函数,并且总是存在运气不好或故意的恶意将运行为 O(N^2) 的情况。
但一般来说,D&C 算法的复杂性是由于解决子问题和合并解决方案的成本的组合。回到您的问题,如果合并解决方案的成本是用朴素算法解决问题的顺序,那么您的 D&C 算法将永远不会胜过朴素算法。
您可以(几乎)总是使用 Master theorem 计算出某些 D&C 算法的复杂性:
https://en.wikipedia.org/wiki/Master_theorem_(analysis_of_algorithms)
D&C 只是设计算法的元策略,这些算法可能会或可能不会更好地解决某个问题;不能保证“成功”,即复杂性较低,更不用说最低的了。
例如,QuickSort 在随机对数线性时间内运行,并且在标准硬件中对通用数组进行排序具有可接受的平均性能,但在特定情况下(例如整数数组)或硬件架构(例如大规模并行计算机)。
【讨论】:
随机快速排序是缓解此类厄运情况的一种方法。大多数编程语言倾向于使用归并排序的变体。【参考方案2】:快速排序不是分而治之的好例子,因为它对数据排序的主要功能(
典型的自上而下合并排序是一个更好的例子,因为它除了通过递归调用将索引(或指针)压入堆栈之外什么都不做,并且在出现两个子数组大小为 1 的实例之前不会进行合并。然后合并完成,跟随调用链上下。然而,自下而上的归并排序会跳过所有索引的递归生成,并首先将包含 n 个元素的数组视为大小为 1 的 n 个子数组,然后立即开始合并。自顶向下主要用于教育目的,而大多数图书馆使用自底向上合并排序和插入排序的某种混合。
【讨论】:
你是说在某些 D&C 中,你会得到更小的块来操作,即使没有并行性也会降低时间复杂度? @releseabe - 来自wiki article - “分治算法通过递归地将问题分解为两个或多个相同或相关类型的子问题,直到这些子问题变得简单足以直接解决。然后将子问题的解决方案组合起来,以解决原始问题。所以目标是简化问题而不是降低时间复杂度。通常“足够简单”是指“基本情况”。对于自上而下的归并排序,基本情况是除法产生大小为 1 的子数组。 这并不意味着它们不会(有时)降低时间复杂度吗?我当然读过这篇文章,但***对我来说不是权威——我已经看到它在某些地方是非常错误的(不是专门在计算机科学领域)。 再次,我问是否有时它会降低时间复杂度 @relseabe - 我删除了一些之前的 cmets 以避免触发聊天。通常“更简单”并不更快。对于特定元素值的排序数组的二进制搜索可以被认为类似于分而治之,因为每次迭代都在前一次迭代中的 1/2 元素上工作。时间复杂度是 O(log(n)),而扫描是 O(n)。在这种情况下,“分而治之”并不比简单的扫描更简单,而是更快,因此“更简单”通常不会更快的一般性也不例外。以上是关于分而治之:解决子问题明显快于未分问题是效率的一部分吗?的主要内容,如果未能解决你的问题,请参考以下文章