1、搜索算法的剪枝優化

       搜索算法按搜索的方式分有兩類,一類是深度優先搜索,一類是廣度優先搜索。我們知道,深度搜索編程簡單,程序簡潔易懂,空間需求也比較低,但是這種方法的 時間複雜度往往是指數級的,倘若不加優化,其時間效率簡直無法忍受;而廣度優先搜索雖然時間複雜度比前者低一些,但其龐大的空間需求量又往往讓人望而卻步。
所以,對程序進行優化,就成爲搜索算法編程中最關鍵的一環。本文所要討論的便是搜索算法中優化程序的一種基本方法叫“剪枝”。
 一、what is it?
       搜索的進程可以看作是從樹根出發,遍歷一棵倒置的樹——搜索樹的過程。而所謂剪枝,顧名思義,就是通過某種判斷,避免一些不必要的遍歷過程,形象的說,就是剪去了搜索樹中的某些“枝條”,故稱剪枝。應用剪枝優化的核心問題是設計剪枝判斷方法,即確定哪些枝條應當捨棄,哪些枝條應當保留的方法。
二、剪枝的原則
原則之一:正確性。    因爲它能夠“剪去”搜索樹中的一些“枝條”。然而,如果在剪枝的時候,將“長有”我們所需要的解的枝條也剪掉了,那麼,一切優化也就都失去了意義。所以,對剪枝的第一個要求就是正確性,即必須保證不丟失正確的結果,這是剪枝優化的前提。我們利用“必要條件”來進行剪枝判斷。也就是說,通過解所必須具備的特徵、必須滿足的條件等方面來考察待判斷的枝條能否被剪枝。這樣,就可以保證所剪掉的枝條一定不是正解所在的枝條。
原則之二:準確性。
即能夠儘可能多的剪去不能通向正解的枝條。準確性可以說是剪枝優化的生命。
原則之三:高效性。
 經常還需要提高判斷操作本身的時間效率。
 綜上所述,我們可以把剪枝優化的主要原則歸結爲六個字:正確、準確、高效。
 我們可以把常用的剪枝判斷大致分成以下兩類:
可行性剪枝。
最優性剪枝(上下界剪枝)。
三、可行性剪枝
搜索過程可以看作是對一棵樹的遍歷。在很多情況下,並不是搜索樹中的所有枝條都能通向我們需要的結果,很多的枝條實際上只是一些死衚衕。如果我們能夠在剛剛進入這樣的死衚衕的時候,就能夠判斷出來並立即剪枝,程序的效率往往會得到提高。而所謂可行性剪枝,正是基於這樣一種考慮。
 下面我們舉一個例子——Betsy的旅行(USACO)。
 題目簡述:一個正方形的小鎮被分成N的平方個小方格,Betsy要從左上角的方格到達左下角的方格,並且經過每個方格恰好一次。編程對於給定的N,計算出Betsy能採用的所有的旅行路線的數目。
 我們用深度優先的回溯方法來解決這個問題:Betsy從左上角出發,每一步可以從一個格子移動到相鄰的沒有到過的格子中,遇到死衚衕則回溯,當移動了N2-1步並達到左下角時,即得到了一條新的路徑,繼續回溯搜索,直至遍歷完所有道路。
 但是,僅僅依照上述算法框架編程,時間效率極低,對N=6的情況無法很好的解決,所以,優化勢在必行。對本題優化的關鍵就在於當搜索到某一個步驟時,能夠提前判斷出在後面的搜索過程中是否一定會遇到死衚衕,而可行性剪枝正可以在這裏派上用場。
 我們首先從“必要條件”,即合法的解所應當具備的特徵的角度分析剪枝的方法,主要有兩個方向:對於一條合法的路徑,除出發點和目標格子外,每一箇中間格子都必然有“一進一出”的過程。所以在搜索過程中,必須保證每個尚未經過的可格子都與至少兩個尚未經過的格子相鄰(除非當時Betsy就在它旁邊)。這裏,我們是從微觀的角度分析問題。
在第一個條件的基礎上,我們還可以從宏觀的角度分析,進一步提高剪枝判斷的準確性。顯然,在一個合法的移動方案的任何時刻,都不可能有孤立的區域存在。雖然孤立區域中的每一個格子也可能都有至少兩個相鄰的空的格子,但它們作爲一個整體,Betsy已經不能達到。我們也應當及時判斷出這種情況,並避免之。
 以上兩個剪枝判斷條件都是正確的,其準確度也比較高。但是,僅僅滿足這兩點還不夠,剪枝判斷的操作過程還必須力求高效。假如我們在每次剪枝判斷時,都簡單的對N2個格子進行一遍掃描,其效率的低下可想而知。因此,我們必須儘可能的簡化判斷的過程。
 實際上,由於Betsy的每一次移動,只會影響到附近的格子,所以每次執行剪枝判斷時,應當只對她附近的格子進行檢查:對於第一個剪枝條件,我們可以設一個整型標誌數組,分別保存與每個格子相鄰的沒被經過的格子的數目,Betsy每次移動到一個新位置,都只會使與之相鄰的至多4個格子的標誌值發生變化,只要檢查它們的標誌值即可。而對於第二個剪枝條件,處理就稍稍麻煩一些。但我們仍然可以使用局部分析的方法,即只通過對Betsy附近的格子進行判斷,就確定是否應當剪枝,下圖簡要說明了剪枝的原理:
 

 上圖給出了可以剪枝的三種情況。由於Betsy到過的所有格子都一定是四連通的,所以每種情況下的兩個白色的格子之間必定是不連通的,它們當中必然至少有一個是屬於某個孤立區域的,都一定可以剪枝。
 經過上述的優化,程序的時間效率有了很大的提高
        在應用可行性剪枝的時候,首先要多角度全面分析問題的特點(本題就是從微觀和宏觀兩個角度設計剪枝方法),找到儘可能多的可以剪枝的情況;同時,還必須注意提高剪枝的時間效率,所以我們使用了“局部判斷”的方法,特別是在處理第二個剪枝條件時,更是通過局部判斷來體現整體性質(是否有孤立區域),這一技巧不僅在設計剪枝方法的時候能夠發揮作用,在其他方面也有着極爲廣泛的應用。
四 、最優性剪枝
       在我們平時遇到的問題中,有一大類是所謂最優化問題,即所要求的結果是最優解。如果我們使用搜索方法來解決這類問題,那麼,最優性剪枝是一定要考慮到的。
      首先要作一些說明:我們知道,解的優劣一般是通過一個評價函數來評判的。這裏定義一個抽象的評價函數——“優度”,它的值越大,對應的解也就越優(對於具體的問題,我們可以認爲“優度”代表正的收益或負的代價等)。 然後,我們再來回顧一下搜索最優解的過程:一般情況下,我們需要保存一個“當前最優解”,實際上就是保存解的優度的一個下界。在遍歷到搜索樹的葉子節點的時候,我們就能得到一個新的解,當然也就得到了它的評價函數值,與保存的優度的下界作比較,如果新解的優度值更大,則這個優度值就成爲新的下界。搜索結束後,所保存的解就是最優解。 那麼,最優性剪枝又是如何進行的呢?當我們處在搜索樹的枝條上時,可以通過某種方法估算出該枝條上的所有解的評價函數的上界,即所謂估價函數。顯然,大於當前保存的優度的下界,是該枝條上存在最優解的必要條件,否則就一定可以剪枝。所以,最優性剪枝也可以稱爲“上下界剪枝”。同時,我們也可以看到,最優性剪枝的核心問題就是估價函數的建立。
         

 

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