常見的算法設計策略

1.分治html

      分治法的設計思想是,將一個難以直接解決的大問題,分割成k個規模較小的子問題,這些子問題相互獨立,且與原問題相同,而後各個擊破,分而治之。算法

      分治法經常與遞歸結合使用:經過反覆應用分治,可使子問題與原問題類型一致而規模不斷縮小,最終使子問題縮小到很容易求出其解,由此天然致使遞歸算法。函數

      根據分治法的分割原則,應把原問題分割成多少個子問題才比較適宜?每一個子問題是否規模相同或怎樣才爲適當?這些問題很難給與確定的回答。但人們從大量實踐中發現,在使用分治法時,最好均勻劃分,且在不少問題中能夠取k=2。這種使子問題規模大體相等的作法源自一種平衡子問題的思想,它幾乎老是比使子問題規模不等的作法好。優化

 

2.動態規劃spa

      動態規劃法與分治法相似,其基本思想也是將原問題分解成若干個子問題。與分治法不一樣的是,其分解出的子問題每每不是相互獨立的。這種狀況下若用分治法會對一些子問題進行屢次求解,這顯然是沒必要要的。動態規劃法在求解過程當中把全部已解決的子問題的答案保存起來,從而避免對子問題重複求解。設計

      動態規劃經常使用於解決最優化問題。對一個最優化問題能否應用動態規劃法,取決於該問題是否具備以下兩個性質:htm

      1.最優子結構性質blog

      當問題的最優解包含其子問題的最優解時,稱該問題具備最優子結構性質。遞歸

      要證實原問題具備最優子結構性質,一般採用反證法。假設由問題的最優解導出的子問題的解不是最優的,而後再設法說明在該假設下可構造出比原問題的最優解更好的解,從而致使矛盾。隊列

      2.子問題重疊性質

      子問題重疊性質是指由原問題分解出的子問題不是相互獨立的,存在重疊現象。

 

      用動態規劃法解題過程當中,應當先找出最優解的結構特徵,即原問題的最優解與其子問題的最優解的關聯。而後有以下兩種程序設計方法:

       1.自底向上遞歸法

       利用問題的最優子結構性質,以自底向上的方式遞歸地從子問題的最優解逐步構造出整個問題的最優解。

       2.自頂向下遞歸法(即備忘錄法)

       利用問題的最優子結構性質,用與直接遞歸法相同的控制結構自頂向下地進行遞歸求解。初始時在表格中爲每一個子問題存入一個標識解。在求解過程當中,對每一個待求子問題,首先查看錶格中相應的記錄項。若記錄項爲初始時的標識值,則表示該子問題是初次遇到,此時應利用問題的最優子結構性質進行遞歸求解,並將結果存入表格,以備之後查看。不然則說明該問題已被求解過,直接返回表格中相應的值便可,沒必要從新計算。

      當一個問題的全部子問題都要求解時,應當用自底向上遞歸法。當子問題空間中的部分子問題可沒必要求解時,自底向上遞歸法會進行多餘的計算,此時應採用自頂向下遞歸法。

 

3.貪心

      當一個問題具備最優子結構性質時,可用動態規劃法求解。但有時會有比動態規劃更簡單更直接效率更高的算法——貪心法。貪心法老是作出在當前看來最好的選擇,也就是說貪心法並不從總體最優考慮,它所作出的選擇只是在某種意義上的局部最優選擇。雖然貪心法並不能對全部問題都獲得總體最優解,可是對許多問題它能產生總體最優解。有些狀況下,貪心法雖然不能獲得總體最優解,但其最終結果倒是最優解的很好的近似。

      貪心法經常使用於解決最優化問題。對一個最優化問題能否應用貪心法,取決於該問題是否具備以下兩個性質:

      1.貪心選擇性質

      貪心選擇性質是指原問題總有一個總體最優解可經過當前的局部最優選擇,即貪心選擇來達到。

      對於一個具體問題,要肯定它是否具備貪心選擇性質,一般可考察問題的一個總體最優解,並證實可修改這個最優解,使其以貪心選擇開始。由此證實該問題總有一個最優解可經過貪心選擇獲得,即具備貪心選擇性質。

     2. 最優子結構性質

      這一點與動態規劃相同。作出貪心選擇後,因爲最優子結構性質,原問題簡化爲規模更小的相似子問題。若是將子問題的最優解和以前所作的貪心選擇合併,則可獲得原問題的一個最優解。

 

      貪心問題的總體最優解可經過一系列局部的最優選擇,即貪心選擇來達到。這也是貪心法與動態規劃的主要區別。在動態規劃中,每一步所作出的選擇每每依賴於相關子問題的解。於是只有在解出相關子問題後,才能作出選擇。而在貪心法中,僅作出當前狀態下的最好選擇,即局部最優選擇。而後再去解作出這個選擇以後產生的相應的子問題。貪心法所作出的貪心選擇能夠依賴於以往所作過的選擇,但毫不依賴於未來所作的選擇,也不依賴於子問題的解。正是因爲這種差異,動態規劃一般以自頂向上的方式解各子問題,而貪心法一般以自頂向下的方式進行,以迭代的方式作出相繼的貪心選擇,每作出一次貪心選擇就將所求問題簡化爲規模更小的子問題。

     

4.回溯

      回溯法是對問題的解空間樹進行深度優先搜索 ,可是在對每一個節點進行DFS以前,要先判斷該節點是否有可能包含問題的解。若是確定不包含,則跳過對以該節點爲根的子樹的搜索,逐層向其祖先節點回溯。若是有可能包含,則進入該子樹,進行DFS。  

      回溯法一般的解題步驟以下:

     (1)定義問題的解空間。

     (2)將解空間組織成便於進行DFS的結構,一般採用樹或圖的形式。

     (3)對解空間進行DFS,並在搜索過程當中用剪枝函數避免無效搜索。

      用回溯法解題時並不須要顯式地存儲整個解空間,而是在DFS過程當中動態地產生問題的解空間。在任什麼時候刻,算法只保存從根節點到當前節點的路徑。若是解空間樹的高度爲h,則回溯法的空間複雜度一般爲O(h) 

      用回溯法解題時,常會遇到如下兩類典型的解空間樹:

      (1)當所給的問題是從n個元素的集合S中找出S知足某種性質的子集時,相應的解空間樹稱爲子集樹,例如http://www.cnblogs.com/laifeiyao/p/3481800.html

      (2)當所給的問題是找出n個元素知足某種性質的排列時,相應的解空間樹稱爲排列樹,例如http://www.cnblogs.com/laifeiyao/p/3492758.html

      回溯法中的剪枝函數一般分爲兩類:

      (1)用約束函數在指定節點處剪去不知足約束的子樹,例如http://www.cnblogs.com/laifeiyao/p/3481800.html

      (2)用限界函數在指定節點處剪去得不到最優解的子樹,例如http://www.cnblogs.com/laifeiyao/p/3492758.html

 

5.分支限界      

      回溯法是對解空間進行深度優先搜索,事實上任何搜索遍整個解空間的算法都可解決問題。因此採用通用圖搜索(樹可抽象爲特殊的圖)的任何實現做爲搜索策略都可解決問題,只要作到窮舉便可。除了深度優先搜索以外,咱們還可採用廣度優先搜索,而分支限界法則是對解空間進行優先級優先搜索。

      分支限界法的搜索策略是,在當前節點處,先生成其全部的子節點(分支),併爲每一個知足約束條件的子節點計算一個函數值(限界),再將知足約束條件的子節點所有加入解空間樹的活結點優先隊列。而後再從當前的活節點優先隊列中選擇優先級最大的節點(節點的優先級由其限界函數的值來肯定) 做爲新的當前節點。重複這一過程,直到到達一個葉節點爲止。所到達的葉節點就是最優解。                                                                                                                                                                                                                                      

相關文章
相關標籤/搜索