五大常用算法之-貪心算法

基本概念

貪心算法是指,在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,它所做出的僅僅是在某種意義上的局部最優解
貪心算法沒有固定的算法框架,算法設計的關鍵是貪心策略的選擇。必須注意的是,貪心算法不是對所有問題都能得到整體最優解,選擇的貪心策略必須具備無後效性(即某個狀態以後的過程不會影響以前的狀態,只與當前狀態有關)。

貪心算法的基本思路

  1. 建立數學模型來描述問題
  2. 把求解的問題分成若干個子問題
  3. 對每個子問題求解,得到子問題的局部最優解
  4. 把子問題的解局部最優解合成原來問題的一個解

算法存在的問題

  • 不能保證求得的最後解是最佳的
  • 不能用來求最大值或最小值的問題
  • 只能滿足某些約束條件可行解的範圍

貪心算法適用的問題

貪心策略適用的前提是:局部最優策略能導致產生全局最優解。

實際上,貪心算法適用的情況很少。一般對一個問題分析是否適用於貪心算法,可以先選擇該問題下的幾個實際數據進行分析,就可以做出判斷

貪心選擇性質

貪心選擇性質是指所求問題的整體最優解可以通過一系列局部最優的選擇,換句話說,當考慮做何種選擇的時候,我們只考慮對當前問題最佳的選擇而不考慮子問題的結果。這是貪心算法可行的第一個基本要素。貪心算法以迭代的方式作出相繼的貪心選擇,每作一次貪心選擇就將所求問題簡化爲規模更小的子問題。對於一個具體問題,要確定它是否具有貪心選擇性質,必須證明每一步所作的貪心選擇最終導致問題的整體最優解。

當一個問題的最優解包含其子問題的最優解時,稱此問題具有最優子結構性質。問題的最優子結構性質是該問題可用貪心算法求解的關鍵特徵

貪心算法的實現框架

從問題的某一初始解出發:
while (朝給定總目標前進一步)
{
利用可行的決策,求出可行解的一個解元素。
}
由所有解元素組合成問題的一個可行解;

例題分析

  • 揹包問題】有一個揹包,容量是M=150,有7個物品,物品可以分割成任意大小。要求儘可能讓裝入揹包中的物品總價值最大,但不能超過總容量。

物品: A B C D E F G
重量:35 30 60 50 40 10 25
價值:10 40 30 50 35 40 30

分析
目標函數: pi\sum{p_i} 最大
約束條件是裝入的物品總質量不超過揹包容量:wiM(M=150)\sum{w_i}\le M(M=150)

  1. 根據貪心的策略,每次挑選價值最大的物品裝入揹包,得到的結果是否最優?
  2. 每次挑選所佔重量最小的物品裝入是否能得到最優解?
  3. 每次選取單位重量價值最大的物品,成爲解本題的策略

值得注意的是,貪心算法並不是完全不可以使用,貪心策略一旦經過證明成立後,它就是一種高效的算法。比如,求最小生成樹的Prim算法Kruskal算法都是漂亮的貪心算法
貪心算法還是很常見的算法之一,這是由於它簡單易行,構造貪心策略不是很困難。
可惜的是,它需要證明後才能真正運用到題目的算法中。
一般來說,貪心算法的證明圍繞着:整個問題的最優解一定由在貪心策略中存在的子問題的最優解得來的。
對於例題中的3種貪心策略,都是無法成立(無法被證明)的,解釋如下:

<1> 貪心策略:選取價值最大者。
反例

W=30
物品:A B C
重量:28 12 12
價值:30 20 20

根據策略,首先選取物品A,接下來就無法再選取了,可是,選取B、C則更好。

<2> 貪心策略:選取重量最小。
反例

W=30
物品:A B C
重量:28 12 12
價值:40 15 15

<3> 貪心策略:選取單位重量價值最大的物品。
反例

W=30
物品:A B C
重量:28 20 10
價值:28 20 10

根據策略,三種物品單位重量價值一樣,程序無法依據現有策略作出判斷,如果選擇A,則答案錯誤。但是果在條件中加一句當遇見單位價值相同的時候,優先裝重量小的,這樣的問題就可以解決.

所以需要說明的是,貪心算法可以與隨機化算法一起使用,具體的例子就不再多舉了。(因爲這一類算法普及性不高,而且技術含量是非常高的,需要通過一些反例確定隨機的對象是什麼,隨機程度如何,但也是不能保證完全正確,只能是極大的機率正確)。

應用舉例

  1. 剪繩子
  2. 驗證迴文字符串II
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章