貪婪算法

貪婪算法

貪婪算法(Greedy Algorithm)也叫算貪心法,貪婪法.它是一個遵循啓發式解決問題的算法範式.它的核心思想就是通過在每一步的選擇中都選用當前步驟下最優的選擇,期望結果是最優的算法.如 旅行推銷員問題.

貪婪算法尤其適用於有最優子結構的問題中,最優子結構的意思是局部的最優解可以導出全局的最優解.貪婪算法與動態規劃 的不同在於貪婪算法對每一個子問題都作出選擇,不能回退;動態規劃則會保存以前的運算結果,根據以前的結果對當前進行選擇,可以回退.

貪婪算法可以解決一些最優化(如最大值最小值等)問題,比如求圖中的最小生成樹、求哈夫曼編碼…其他大多數的情況都不適用貪婪算法,一旦一個問題可以使用貪婪算法來解決,那麼貪婪算法一般是解決這個問題的最好辦法.由於貪婪算法的高效性以及其答案比較接近最有結果,也可以作爲輔助算法或直接解決一些結果要求不那麼精確的問題.

原文首發於 https://leonchen1024.com/2018/12/03/Greedy-Algorithm/

原理

步驟

  1. 建立數學模型來描述問題,並建立一個備選答案區

  2. 把求解的問題分成若干個子問題,

  3. 使用一個選擇函數對每個子問題求解最優解,並判斷是否可用於整體問題

  4. 把所有子問題的最優解合成一個整的解

適用情況

貪婪算法適用於一些數學問題等,大部分適用的問題都有兩個特點:

Greedy choice property (貪婪選擇的屬性)

我們可以在每個子問題找出最好的選擇然後進行總結.貪婪算法可能會根據迄今爲止已經做的選擇進行計算,但是卻不會考慮之後子問題的選擇.它將一個大的問題分解成小的問題並一個一個進行迭代計算.換句話說,貪婪算法不會重新考慮它已經得出的選擇.這是它和 dynamic programming 的主要區別,動態規劃會詳盡的計算並確保得到最優解,在一步之後,動態規劃會根據之前所有得到的選擇進行下一個選擇,並可能會重新對之前步驟的算法路徑進行修改.

Optimal substructure (最優子結構)

這個問題要包含optimal substructure(即這個問題的最優解包含了它的子問題的最優解)

如以下幾種類型的問題

原文首發於 https://leonchen1024.com/2018/12/03/Greedy-Algorithm/

Matroids (擬陣)

matroid(擬陣) 是一個數學上的結構,它將linear independence (線性無關)的概念從 vector spaces (向量空間)推廣到了任意的集合.如果一個最優解問題有一個擬陣結構,那麼貪婪算法是最佳的解決辦法.

Submodular functions(子模塊函數)

一個函數 ff 定義了當集合 Ω\Omega 的所有子集合 S,TΩS,T \subseteq \Omega 都滿足 f(S)+f(T)f(ST)+f(ST)f(S)+f(T)\geq f(S\cup T)+f(S\cap T) 的情況即爲子模塊.

假設有人想要找到一個集合 SS 使得函數 ff 最大.貪婪算法將會通過逐個添加在每一步中使得 ff 增加最多的元素,產生一個結果至少是 (11/e)maxXΩf(X)(1-1/e)\max _{X\subseteq \Omega }f(X) ??todo. 所以,貪婪算法至少得出最優解的 (11/e)0.63(1-1/e) \approx 0.63倍的解.

其他一些相對可以使用的問題

這些問題也可以使用貪婪算法,但不是最好的解法,他們在最差的情況下,可能會得到很差的結果.

失敗的情況

原文首發於 https://leonchen1024.com/2018/12/03/Greedy-Algorithm/

在很多其他問題上,貪婪算法無法產生最優解,甚至可能產生一個最壞的解決方案.比如之前提到的 traveling salesman problem :對每一個城市都要計算一個最近的鄰居,這種方式可能會產生一個最壞的路程.

比如下圖,貪婪算法只考慮到下一步的最優解,但是卻沒有考慮到之後的解決方案,導致實際上得出的不是一個最優解.

Greedy-search-path-example

Application

貪婪法基本上(但並不是一定)不適用於求全局最優解,因爲他通常沒有遍歷所有的數據。他們太早給出了肯定的選擇使得他們無法從所有的解法中找到最優解。比如,使用 greedy coloring 算法來解決 graph coloring problem 以及所有的 NP-complete 問題。儘管如此,貪婪法還是很有用的,因爲他們容易被考慮到並且通常情況下會給出一個比較好的解法。

如果一個貪婪算法可以被證明是某個問題的全局最優解法,他通常情況下就會成爲優先選擇的方法,因爲它比其他的最優解方法如 dynamic programming 要快。這種例子有使用 Kruskal’s algorithmPrim’s algorithm 找到minimum spanning trees,還有找到最優 Huffman trees.

貪心法也使用於 網絡 路由 中。使用貪心路由,消息會被髮送到距離目標節點“最近”的相鄰節點。一個節點位置的定義(還有“最近”的含義)也許會取決於它的物理位置,如同在 ad hoc networks 中使用 geographic routing . 位置也可能會使一個人造的結構如同在 small world routingdistributed hash table 中.

Reference

https://en.wikipedia.org/wiki/Greedy_algorithm

About Me

我的博客 leonchen1024.com

我的 GitHub https://github.com/LeonChen1024

微信公衆號

wechat

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章