貪婪算法(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…
微信公衆號