其實就是些正確的廢話……沒有很大的參考價值,但分類部分可以讓思考更有條理一點
轉載自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*)),速度明顯會比亂搜更快。
搜索的復雜度明顯講不清,這種剪枝自然是能加就加。