贪婪算法(Greedy Algorithm)也叫算贪心法,贪婪法.它是一个遵循启发式解决问题的算法范式.它的核心思想就是通过在每一步的选择中都选用当前步骤下最优的选择,期望结果是最优的算法.如 旅行推销员问题 . 贪婪算法尤其适用于有最优子结构的问题中,最优子结构的意思是局部的最优解可以导出全局的最优解.贪婪算法与 动态规划 的不同在于贪婪算法对每一个子问题都作出选择,不能回退;动态规划则会保存以前的运算结果,根据以前的结果对当前进行选择,可以回退. 贪婪算法可以解决一些 最优化 (如最大值最小值等)问题,比如求图中的 最小生成树 、求 哈夫曼编码 …其他大多数的情况都不适用贪婪算法,一旦一个问题可以使用贪婪算法来解决,那么贪婪算法一般是解决这个问题的最好办法.由于贪婪算法的高效性以及其答案比较接近最有结果,也可以作为辅助算法或直接解决一些结果要求不那么精确的问题. 原文首发于 贪婪算法适用于一些数学问题等,大部分适用的问题都有两个特点: 我们可以在每个子问题找出最好的选择然后进行总结.贪婪算法可能会根据迄今为止已经做的选择进行计算,但是却不会考虑之后子问题的选择.它将一个大的问题分解成小的问题并一个一个进行迭代计算.换句话说,贪婪算法不会重新考虑它已经得出的选择.这是它和 dynamic programming 的主要区别,动态规划会详尽的计算并确保得到最优解,在一步之后,动态规划会根据之前所有得到的选择进行下一个选择,并可能会重新对之前步骤的算法路径进行修改. 这个问题要包含 optimal substructure (即这个问题的最优解包含了它的子问题的最优解) 如以下几种类型的问题 原文首发于 matroid (拟阵) 是一个数学上的结构,它将 linear independence (线性无关)的概念从 vector spaces (向量空间)推广到了任意的集合.如果一个最优解问题有一个拟阵结构,那么贪婪算法是最佳的解决办法. 一个函数 定义了当集合 的所有子集合 都满足 的情况即为子模块. 假设有人想要找到一个集合 使得函数 最大.贪婪算法将会通过逐个添加在每一步中使得 增加最多的元素,产生一个结果至少是 ??todo. 所以,贪婪算法至少得出最优解的 倍的解. 这些问题也可以使用贪婪算法,但不是最好的解法,他们在最差的情况下,可能会得到很差的结果. 原文首发于 在很多其他问题上,贪婪算法无法产生最优解,甚至可能产生一个最坏的解决方案.比如之前提到的 traveling salesman problem :对每一个城市都要计算一个最近的邻居,这种方式可能会产生一个最坏的路程. 比如下图,贪婪算法只考虑到下一步的最优解,但是却没有考虑到之后的解决方案,导致实际上得出的不是一个最优解. 贪婪法基本上(但并不是一定)不适用于求全局最优解,因为他通常没有遍历所有的数据。他们太早给出了肯定的选择使得他们无法从所有的解法中找到最优解。比如,使用 greedy coloring 算法来解决 graph coloring problem 以及所有的 NP-complete 问题。尽管如此,贪婪法还是很有用的,因为他们容易被考虑到并且通常情况下会给出一个比较好的解法。 如果一个贪婪算法可以被证明是某个问题的全局最优解法,他通常情况下就会成为优先选择的方法,因为它比其他的最优解方法如 dynamic programming 要快。这种例子有使用 Kruskal's algorithm 和 Prim's algorithm 找到 minimum spanning trees ,还有找到最优 Huffman trees . 贪心法也使用于 网络 路由 中。使用贪心路由,消息会被发送到距离目标节点“最近”的相邻节点。一个节点位置的定义(还有“最近”的含义)也许会取决于它的物理位置,如同在 ad hoc networks 中使用 geographic routing . 位置也可能会使一个人造的结构如同在 small world routing 和 distributed hash table 中. 我的博客 我的 GitHub 微信公众号 [图片上传失败...(image-ee4c03-68)]