数据结构与算法——贪心算法简介

贪心算法是一种算法范式,它遵循在每个阶段做出局部最优选择的问题解决启发式,希望找到全局最优。换句话说,贪心算法在每一步都选择最好的选项,而不考虑该选择对未来步骤的影响。

当一个问题可以分解成更小的子问题,并且每个子问题的解决方案可以组合起来解决整体问题时,贪心算法很有用。贪心算法可用于解决涉及在许多可能的解决方案中寻找最佳解决方案的优化问题。

可以使用贪心算法解决的问题的一个典型例子是“硬币找零”问题。问题是用尽可能少的硬币找零给定的钱数。例如,如果金额为 25 美分,可用硬币为 1 美分、5 美分和 10 美分,那么贪心算法将在每一步选择最大的硬币。首先选择一个 10 美分的硬币,然后是另一个 10 美分的硬币,最后是一个 5 美分的硬币,总共三个硬币。

然而,贪心算法不一定总能找到最优解。例如,如果可用的硬币是 1 美分、3 美分和 4 美分,金额是 6 美分,贪心算法会选择一个 4 美分的硬币和两个 1 美分的硬币,而最优解是用两个3 美分的硬币。

因此,证明贪心算法的正确性并了解其局限性很重要。贪心算法可以应用于许多上下文,包括调度、图论和动态规划。

贪心算法被定义为一种解决优化问题的方法,无论最终结果如何,它都会做出能带来最明显和最直接利益的决策。它适用于最小化最大化导致所需解决方案的情况。

贪心算法的特点

对于使用贪婪方法解决的问题,它必须遵循几个主要特征:

  • 有一个有序的资源列表(利润、成本、价值等) 
  • 获取所有资源中的最大值(最大利润、最大值等)。 
  • 例如,在分数背包问题中,根据可用容量首先取最大值/重量。 

贪心算法的使用:-

贪心算法是一种用于优化问题的方法,其目标是在每个阶段做出局部最优选择,以期找到全局最优。之所以称为“贪心”,是因为它试图通过在每一步做出最佳选择来找到最佳解决方案,而不考虑未来步骤或当前决策的后果。

贪心算法的一些常见用例包括:

调度和资源分配:贪心算法可用于高效地调度作业或分配资源。

最小生成树:贪心算法可以用来寻找一个图的最小生成树,它是连接所有顶点的总边权最小的子图。

硬币找零问题:贪心算法可用于以最少数量的硬币找零给定数量,方法是始终选择价值最高且小于要找零的剩余数量的硬币。

霍夫曼编码:贪婪算法可用于生成用于数据压缩的无前缀代码,通过以考虑每个字符的频率的方式构建二叉树。

需要注意的是,并非所有优化问题都可以通过贪心算法解决,并且在某些情况下贪心算法可能会导致次优解决方案。然而,在许多情况下,贪心算法提供了对最优解的良好近似,是快速有效地解决优化问题的有用工具。

所有贪心算法都遵循一个基本结构: 

  1. 声明一个空结果 = 0。
  2. 我们做一个贪婪的选择来选择,如果选择可行就把它加到最终结果中。
  3. 返回结果。

为什么选择贪心法?

贪婪的方法有一些权衡,这可能使其适合优化。一个突出的原因是立即获得最可行的解决方案。在活动选择问题(下面解释)中,如果在完成当前活动之前可以完成更多活动,则可以在同一时间内执行这些活动。另一个原因是根据条件递归地划分问题,而不需要组合所有的解决方案。在活动选择问题中,“递归划分”步骤是通过仅扫描一次项目列表并考虑某些活动来实现的。

贪心算法示例:

一些具有最优子结构特性并且可以使用贪心方法解决的著名问题是 –

1)作业排序问题

首先贪婪地选择利润最大的工作,按照利润的递减顺序对工作进行排序。这将有助于最大化总利润,因为为每个时间段选择利润最大的工作最终将使总利润最大化

2) Prim 求最小生成树的算法

它以一个空的生成树开始。这个想法是维护两组顶点。第一组包含已包含在 MST 中的顶点,另一组包含尚未包含的顶点。在每一步,它都会考虑连接这两个集合的所有边,并从这些边中选择权重最小的边。选择边缘后,它将边缘的另一个端点移动到包含 MST 的集合。 

贪心算法是如何工作的?

如果在没有进行彻底检查的情况下选择应用贪心法,那么使用它的决定可能会有些困难,有时甚至会导致失败。在某些情况下,采用局部最佳选择可能会导致失去全局最优解。 

例如: 

  • 贪心法失败的一个例子是在给定图中找到节点的最大加权路径。

数据结构与算法——贪心算法简介_第1张图片

带加权顶点的图

  • 在上图中,从根节点10开始,如果我们贪婪地选择下一个节点以获得最大权重路径,则下一个选择的节点将为5,这将使总和为15,并且路径将结束,因为没有5的子节点但是路径10 -> 5不是最大权重路径。

数据结构与算法——贪心算法简介_第2张图片

贪心方法失败

  • 为了找到权重最大的路径,必须计算所有可能的路径总和,并且必须比较它们的路径总和以获得所需的结果,可以看出上图中权重最大的路径是 10 -> 1 -> 30,这给出了路径总和41 . 

数据结构与算法——贪心算法简介_第3张图片

正确的方法

  • 在这种情况下,贪婪方法将不起作用,而是必须考虑 从叶节点的完整路径以获得正确答案,即权重最大的路径,这可以通过递归检查所有路径并计算它们的权重来实现。

因此要使用贪心算法,问题不能包含重叠的子问题。

贪心算法与动态规划

贪心算法和动态规划是解决复杂规划问题的两种最广泛使用的算法范式,而贪婪方法适用于局部最优选择导致全局最优解的问题动态规划适用于具有重叠子问题结构的问题,其中子问题的答案是需要解决其他几个子问题。详细区别见下表: 

特征

贪心算法 动态规则

可行性 

在贪心算法中,我们会做出目前看来最好的选择,希望它会导致全局最优解。 在动态规划中,我们在考虑当前问题和先前解决的子问题的解决方案的每一步做出决策,以计算最优解。

最优性

在贪心法中,有时无法保证获得最优解。 保证动态规划将生成最佳解决方案,因为它通常会考虑所有可能的情况,然后选择最佳解决方案。

递归

贪心法遵循在每个阶段做出局部最优选择的问题解决启发式。 动态规划是一种算法技术,通常基于使用一些先前计算的状态的循环公式。

记忆化                                   

它在记忆方面更有效率,因为它从不回顾或修改以前的选择 它需要用于记忆的动态编程表,并且增加了它的内存复杂性。

    时间复杂度                    

贪心方法通常更快。例如,Dijkstra 的最短路径算法需要O(ELogV + VLogV)时间。 动态规划通常较慢。例如,Bellman Ford 算法需要O(VE)时间。

时尚

贪婪方法通过以串行前向方式做出选择来计算其解决方案,从不回头或修改以前的选择。 动态规划通过从较小的最优子​​解中综合它们来自下而上或自上而下地计算其解。

你可能感兴趣的:(算法,贪心算法,算法,动态规划)