剪枝優化策略


其實就是些正確的廢話……沒有很大的參考價值,但分類部分可以讓思考更有條理一點

轉載自https://blog.csdn.net/u010700335/article/details/44079069

一:剪枝策略的尋找的方法

 

1)微觀方法:從問題本身出發,發現剪枝條件

2)宏觀方法:從整體出發,發現剪枝條件。

3)注意提高效率,這是關鍵,最重要的。

總之,剪枝策略,屬於算法優化范疇;通常應用在DFS 和 BFS 搜索算法中;剪枝策略就是尋找過濾條件,提前減少不必要的搜索路徑。

二:剪枝算法(算法優化)

 

1、簡介

    在搜索算法中優化中,剪枝,就是通過某種判斷,避免一些不必要的遍歷過程,形象的說,就是剪去了搜索樹中的某些“枝條”,故稱剪枝。應用剪枝優化的核心問題是設計剪枝判斷方法,即確定哪些枝條應當舍棄,哪些枝條應當保留的方法。

2、剪枝優化三原則: 正確、准確、高效.原則

     搜索算法,絕大部分需要用到剪枝.然而,不是所有的枝條都可以剪掉,這就需要通過設計出合理的判斷方法,以決定某一分支的取舍. 在設計判斷方法的時候,需要遵循一定的原則.

剪枝的原則

  1) 正確性

  正如上文所述,枝條不是愛剪就能剪的. 如果隨便剪枝,把帶有最優解的那一分支也剪掉了的話,剪枝也就失去了意義. 所以,剪枝的前提是一定要保證不丟失正確的結果.

  2)准確性

  在保證了正確性的基礎上,我們應該根據具體問題具體分析,采用合適的判斷手段,使不包含最優解的枝條盡可能多的被剪去,以達到程序“最優化”的目的. 可以說,剪枝的准確性,是衡量一個優化算法好壞的標准.

 3)高效性

設計優化程序的根本目的,是要減少搜索的次數,使程序運行的時間減少. 但為了使搜索次數盡可能的減少,我們又必須花工夫設計出一個准確性較高的優化算法,而當算法的准確性升高,其判斷的次數必定增多,從而又導致耗時的增多,這便引出了矛盾. 因此,如何在優化與效率之間尋找一個平衡點,使得程序的時間復雜度盡可能降低,同樣是非常重要的. 倘若一個剪枝的判斷效果非常好,但是它卻需要耗費大量的時間來判斷、比較,結果整個程序運行起來也跟沒有優化過的沒什么區別,這樣就太得不償失了.

 

3、分類

   剪枝算法按照其判斷思路可大致分成兩類:可行性剪枝及最優性剪枝.

3.1 可行性剪枝 —— 該方法判斷繼續搜索能否得出答案,如果不能直接回溯。

3.2 最優性剪枝

    最優性剪枝,又稱為上下界剪枝,是一種重要的搜索剪枝策略。它記錄當前得到的最優值,如果當前結點已經無法產生比當前最優解更優的解時,可以提前回溯。

 

補完分類:轉載自https://www.cnblogs.com/fenghaoran/p/6391016.html

1.可行性剪枝。

如果當前條件不合法就不再繼續搜索,直接return。這是非常好理解的剪枝,搜索初學者都能輕松地掌握,而且也很好想。一般的搜索都會加上。

一般格式:

dfs(int x)
{
if(x>n)return;
if(!check1(x))return;
....
return;
}

 

2.最優性剪枝。

           如果當前條件所創造出的答案必定比之前的答案大,那么剩下的搜索就毫無必要,甚至可以剪掉。

   我們利用某個函數估計出此時條件下答案的‘下界’,將它與已經推出的答案相比,如果不比當前答案小,就可以剪掉。

   一般格式:

long long ans=987474477434487ll;
... Dfs(int x,...)
{
    if(x... && ...){ans=....;return ...;}
    if(check2(x)>=ans)return ...;    //最優性剪枝 
    for(int i=1;...;++i)
    {
        vis[...]=1; 
        dfs(...);
        vis[...]=0;
    }
}
一般實現:在搜索取和最大值時,如果后面的全部取最大仍然不比當前答案大就可以返回。
在搜和最小時同理,可以預處理后綴最大/最小和進行快速查詢。

3.記憶化搜索。

  記憶化搜索其實很像動態規划(DP)。

它的關鍵是:如果對於相同情況下必定答案相同,就可以把這個情況的答案值存儲下來,以后再次搜索到這種情況時就可以直接調用。

還有就是不能搜出環來,不能互相依賴。

  一般格式:

long long ans=987474477434487ll;
... Dfs(int x,...)
{
    if(x... && ...){ans=....;return ...;}
    if(vis[x]!=0)return f[x];vis[x]=1;
    for(int i=1;...;++i)
    {
        vis[...]=1; 
        dfs(...);
        vis[...]=0;
        f[x]=...;
    }
}

 

4.搜索順序剪枝

  在一些迷宮題,網格題,或者其他搜索中可以貪心的題,搜索順序顯得十分重要。我經常聽見有人說(我自己也說過):“從左邊搜會T,從右邊搜就A了”之類的語句。

  其實在迷宮、網格類的題目中,以左上->右下為例,右下左上就明顯比左上右下優秀。

  在一些推斷搜索題中,從已知信息最多的地方開始搜索顯然更加優秀。

  在一些題中,先搜某個值大的,再搜某個值小的(比如樹的度數,產生答案的預計(A*)),速度明顯會比亂搜更快。

  搜索的復雜度明顯講不清,這種剪枝自然是能加就加。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM