1. 程式人生 > 其它 >回溯法(Backtracking Method)

回溯法(Backtracking Method)

回溯法(探索與回溯法,Backtracking Method)是一種選優搜尋法,又稱為試探法,按選優條件向前搜尋,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術為回溯法,而滿足回溯條件的某個狀態的點稱為“回溯點”。
基本做法就是搜尋,或是一種組織得井井有條的,能避免不必要搜尋的窮舉式搜尋法 —— 適用於解一些組合數相當大的問題。

用爬山來比喻回溯,好比從山腳下找一條爬上山頂的路,起初有好幾條道可走,當選擇一條道走到某處時,又有幾條岔道可供選擇,只能選擇其中一條道往前走,若能這樣子順利爬上山頂則罷了,否則走到一條絕路上時,只好返回到最近的一個路口,重新選擇另一條沒走過的道往前走。如果該路口的所有路都走不通,只得從該路口繼續回返。照此規則走下去,要麼找到一條到達山頂的路,要麼最終試過所有可能的道,無法到達山頂。
回溯是一種窮舉,但與brute force有一些區別,回溯帶了兩點腦子的,並不多,brute force一點也沒帶。
第一點腦子是回溯知道回頭;相反如果是brute force,發現走不通立刻跳下山摔死,換第二條命從頭換一條路走。
第二點腦子是回溯知道剪枝;如果有一條岔路上放了一坨屎,那這條路我們不走,就可以少走很多不必要走的路。

還有一些愛混淆的概念:遞迴,回溯,DFS。

  • 回溯是一種找路方法,搜尋的時候走不通就回頭換路接著走,直到走通了或者發現此山根本不通。
  • DFS是一種開路策略,就是一條道先走到頭,再往回走一步換一條路走到頭,這也是回溯用到的策略。在樹和圖上回溯時人們叫它DFS。
  • 遞迴是一種行為,回溯和遞迴如出一轍,都是一言不合就回到來時的路,所以一般回溯用遞迴實現;當然也可以不用,用棧。


回溯法在問題的解空間樹中,按深度優先策略,從根結點出發搜尋解空間樹。

  • 演算法搜尋至解空間樹的任意一點時,先判斷該結點是否包含問題的解。
  • 如果肯定不包含,則跳過對該結點為根的子樹的搜尋,逐層向其祖先結點回溯;
  • 否則,進入該子樹,繼續按深度優先策略搜尋。

基本思想

  1. 針對所給問題,定義問題的解空間。
  2. 確定易於搜尋的解空間結構。
  3. 以深度優先方式搜尋解空間,並在搜尋過程中用剪枝函式避免無效搜尋。

方法

  • 遞歸回溯:回溯法對解空間作深度優先搜尋,因此,在一般情況下,用遞迴方法實現回溯法。
  • 迭代回溯:採用樹的非遞迴深度優先遍歷演算法,可將回溯法表示為一個非遞迴迭代過程。

效率分析

回溯演算法的效率在很大程度上依賴於以下因素:

  • 產生x[k]的時間;
  • 滿足顯約束的x[k]值的個數;
  • 計算約束函式constraint的時間;
  • 計算上界函式bound的時間;
  • 滿足約束函式和上界函式約束的所有x[k]的個數。

好的約束函式能顯著地減少所生成的結點數。但這樣的約束函式往往計算量較大。因此,在選擇約束函式時通常存在生成結點數與約束函式計算量之間的折衷。

參考

Backtracking回溯法_grllery的部落格-CSDN部落格

Backtracking (upenn.edu)