一,貪心算法的設計思想
· 從問題的某一個初始解出發逐步逼近給定的目標,每一步都作一個不可回溯的決策,盡可能地求得最好的解。當達到某算法中的某一步不需要再繼續前進時,算法停止。
二,貪心算法的基本性質
1)貪心選擇性質
所謂貪心選擇性質是指所求問題的整體最優解可以通過一系列局部最優的選擇,即貪心選擇來達到。這是貪心算法可行的第一個基本要素,也是貪心法與動態規劃法的主要區別。
2) 最優子結構性質
該問題解的整體最優性依賴于其局部子問題解的最優性。這種性質是可以采用貪心算法解決問題的關鍵特征。例如,活動安排問題,在選擇了一項活動后,它必須是最優的,否則不能得到全局的最優。三,貪心算法的適用性
· 貪心算法對問題只需考慮當前局部信息就要做出決策,也就是說使用貪心算法的前提是“局部最優策略能導致產生全局最優解”。
·該算法的適用范圍較小, 若應用不當, 不能保證求得問題的最佳解。更準確的方法是通過數學方法證明問題對貪心策略的選用性。四,絕對貪心問題
例一:Dijkstra單源最短路徑問題(有向圖)
(Dijkstra)算法思想 按路徑長度遞增次序產生最短路徑算法: 把V分成兩組: (1)S:已求出最短路徑的頂點的集合 (2)V-S=T:尚未確定最短路徑的頂點集合 將T中頂點按最短路徑遞增的次序加入到S中 保證:1)從源點V0到S中各頂點的最短路徑長度都不大于 從V0到T中任何頂點的最短路徑長度 2)每個頂點對應一個距離值 S中頂點:從V0到此頂點的最短路徑長度 T中頂點:從V0到此頂點的只包括S中頂點作中間 頂點的最短路徑長度 依據:可以證明V0到T中頂點Vk的最短路徑,或是從V0到Vk的 直接路徑的權值;或是從V0經S中頂點到Vk的路徑權值之和 求最短路徑步驟 算法步驟如下: 1. 初使時令 S={V0},T={其余頂點},T中頂點對應的距離值 若存在<V0,Vi>,d(V0,Vi)為<V0,Vi>弧上的權值 若不存在<V0,Vi>,d(V0,Vi)為∝ 2. 從T中選取一個其距離值為最小的頂點W且不在S中,加入S 3. 對T中頂點的距離值進行修改:若加進W作中間頂點,從V0到Vi的 距離值比不加W的路徑要短,則修改此距離值 重復上述步驟2、3,直到S中包含所有頂點,即S=T為止輔助數組:dist[ ] 存放V0到T中點距離
path[ ]存放已經加入S中點到V0最短路徑
例二:Kruskal最小生成樹問題(每次選權值最小邊,直到生成一個最小生成樹)
算法的運行時間為 O(nlog n)。
源碼:
五,相對貪心問題
例一,取數游戲。
·問題描述
有2個人輪流取2n個數中的n個數,取數之和大者為勝。設計算法,讓先取數者獲勝,模擬取數過程。
·問題分析
這個游戲一般假設取數者只能看到2n個數中兩邊的數(第一次取時,能看到6,5則取6),用貪心算法的情況:
·例如
若一組數據為:6,16,27,6,12,9,2,11,6,5
用貪心策略每次兩人都取兩邊的數中較大的一個數,先取者勝.以A先取為例:
取數結果為:
A 6,27,12,5,11=61 勝
B 16,6,9,6,2=39
·但若選另一組數據:16,27,7,12,9,2,11,6
仍都用貪心算法,先取者A敗。
取數結果為:
A 16,7,9,11=43
B 27,12,6,2=47 勝
其實,若我們只能看到兩邊的數據,則此題無論先取還是后取都無必勝的策略。這時一般的策略是用近似貪心算法。
但若取數者能看到全部2n個數,則此問題可有一些簡單的方法,有的雖不能保證所取數的和是最大,但確是一個先取者必勝的策略。
六,動態規劃(各個問題包含公共子問題)
1)最優決策原理:要求問題具有最優子結構(即最優解包含子問題的最優解),是一種自底向上的求解思路,與遞歸正好相反,每次求解到一個階段時,該階段求解所依賴的子問題已經完全求解完畢,因此每一步的求解都是在直到全部所需信息的情況下進行的,因此可以得到全局最優解。
2)動態規劃的決策過程:最優決策是在最后階段形成的,然后向前倒推,直到初始階段;而決策的具體結果及所產生的狀態轉移,卻是由初始階段開始進行計算的,然后向后遞歸或迭代,直到最終結果。
3.子問題的重疊性:動態規劃將原來具有指數級復雜度的搜索算法改進成了具有多項式時間的算法。其中的關鍵在于解決冗余,這是動態規劃算法的根本目的。 動態規劃實質上是一種以空間換時間的技術,它在實現的過程中,不得不存儲產生過程中的各種狀態,所以它的空間復雜度要大于其它的算法
例題:著名的貨郎擔(旅行售貨商)問題
詳細解答參見博文------貨郎擔(旅行售貨商)
七,回溯
1)設計思想
回溯與分支限界技術實際上都是基于窮舉方法的,即按照一定規律,把問題所有可能的解組織成某種樹結構,形成可能的解空間樹或狀態空間樹。然后按照具體問題的約束條件,通過各種搜索策略,遍歷可能的解空間樹。從而得到滿足問題條件的解或最優解。兩種算法設計思路相近、本質一致。
2)回溯與分支限界法解決實際問題,大致可分為四個環節:
(1)確定問題的可能解空間,相當于找出進行窮舉的搜索范圍。
(2)以一種便于搜索的方式組織所有的可能解,一般是生成可能解空間樹。
(3)以某種方式搜索可能的解空間樹,有兩種基本搜索方式。即:深度優先搜索方式和,這就是回溯技術;廣度優先搜索,就是分支限界技術。
(4)在搜索過程中利用判定函數,也稱為限界函數,通過“剪枝”來加速搜索過程。
3)回溯法的設計原理
按照深度優先搜索的方式,從根結點出發搜索狀態空間樹。
· 每搜索到達狀態空間樹的一個擴展結點,總是先判斷以該結點為根的子樹是否包含問題的解。如果肯定不包含,則跳過對該結點為根的子樹的進一步搜索,該結點成為一個死結點,同時應向上層回溯至最近的一個活動結點。再以該活動結點作為當前新的擴展結點。以這種方式遞歸地在解空間中搜索,直至找到問題的解,或者解空間中已無活動結點為止,即此問題無解。
· 在回溯法中,為了避免生成那些不可能產生最佳解的問題狀態,要不斷地利用限界函數來處死那些實際上不可能產生所需解的活動結點,以減少問題的計算量。所以,回溯法應是具有限界函數的深度優先搜索法。
用回溯法解題時,常遇到兩類典型的解空間樹,子集樹與排列樹。
例題:著名的八皇后問題
詳細解答參見博文------八皇后問題
八,分支限界(求問題在某種意義下的最優解)
1)分支限界法的設計原理
分支限界法類似于回溯法,也是一種在問題的狀態空間樹上搜索解的算法。但是,分支限界法與回溯法有不同的求解目標。回溯法的求解目標是找出狀態空間樹中的所有回答結點或任一回答結點,分支限界法的求解目標則是找出使得某一目標函數達到極小或極大的一個問題結點。
2)分支限界法與回溯法有兩點不同:
(1)求解目標不同。回溯法的求解目標是找出解空間樹中滿足約束條件的所有解,而分支限界法的求解目標則是找出滿足約束條件的一個解或最優解。
(2)搜索方式不同。回溯法以深度優先的方式搜索解空間樹,而分支限界法則以廣度優先或以最小耗費優先的方式搜索解空間樹。
3)常見的兩種分支限界法
(1)隊列式(FIFO)分支限界法
按照隊列先進先出(FIFO)原則選取下一個結點為擴展結點。
(2)優先隊列式分支限界法
按照優先隊列中規定的優先級選取優先級最高的結點成為當前擴展結點。
4)常見問題
裝箱問題、布線問題、單源最短路徑問題、最大團問題、0-1背包問題、旅行售貨問題