贪婪算法(Greedy Algorithm)也叫算贪心法,贪婪法.它是一个遵循启发式解决问题的算法范式.它的核心思想就是经过在每一步的选择中都选用当前步骤下最优的选择,指望结果是最优的算法.如 旅行推销员问题.git
贪婪算法尤为适用于有最优子结构的问题中,最优子结构的意思是局部的最优解能够导出全局的最优解.贪婪算法与动态规划 的不一样在于贪婪算法对每个子问题都做出选择,不能回退;动态规划则会保存之前的运算结果,根据之前的结果对当前进行选择,能够回退.github
贪婪算法能够解决一些最优化(如最大值最小值等)问题,好比求图中的最小生成树、求哈夫曼编码…其余大多数的状况都不适用贪婪算法,一旦一个问题可使用贪婪算法来解决,那么贪婪算法通常是解决这个问题的最好办法.因为贪婪算法的高效性以及其答案比较接近最有结果,也能够做为辅助算法或直接解决一些结果要求不那么精确的问题.算法
原文首发于 leonchen1024.com/2018/12/03/…微信
创建数学模型来描述问题,并创建一个备选答案区网络
把求解的问题分红若干个子问题,app
使用一个选择函数对每一个子问题求解最优解,并判断是否可用于总体问题函数
把全部子问题的最优解合成一个整的解优化
贪婪算法适用于一些数学问题等,大部分适用的问题都有两个特色:编码
咱们能够在每一个子问题找出最好的选择而后进行总结.贪婪算法可能会根据迄今为止已经作的选择进行计算,可是却不会考虑以后子问题的选择.它将一个大的问题分解成小的问题并一个一个进行迭代计算.换句话说,贪婪算法不会从新考虑它已经得出的选择.这是它和 dynamic programming 的主要区别,动态规划会详尽的计算并确保获得最优解,在一步以后,动态规划会根据以前全部获得的选择进行下一个选择,并可能会从新对以前步骤的算法路径进行修改.spa
这个问题要包含optimal substructure(即这个问题的最优解包含了它的子问题的最优解)
如如下几种类型的问题
原文首发于 leonchen1024.com/2018/12/03/…
matroid(拟阵) 是一个数学上的结构,它将linear independence (线性无关)的概念从 vector spaces (向量空间)推广到了任意的集合.若是一个最优解问题有一个拟阵结构,那么贪婪算法是最佳的解决办法.
一个函数 定义了当集合
的全部子集合
都知足
的状况即为子模块.
假设有人想要找到一个集合 使得函数
最大.贪婪算法将会经过逐个添加在每一步中使得
增长最多的元素,产生一个结果至少是
??todo. 因此,贪婪算法至少得出最优解的
倍的解.
这些问题也可使用贪婪算法,但不是最好的解法,他们在最差的状况下,可能会获得不好的结果.
原文首发于 leonchen1024.com/2018/12/03/…
在不少其余问题上,贪婪算法没法产生最优解,甚至可能产生一个最坏的解决方案.好比以前提到的 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 中.
个人博客 leonchen1024.com
个人 GitHub github.com/LeonChen102…
微信公众号