回溯演算法實際上乙個類似列舉的搜尋嘗試過程,主要是在搜尋嘗試過程中尋找問題的解,當發現已不滿足求解條件時,就「回溯」返回,嘗試別的路徑。
回溯法是一種選優搜尋法,按選優條件向前搜尋,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術為回溯法,而滿足回溯條件的某個狀態的點稱為「回溯點」。
許多複雜的,規模較大的問題都可以使用回溯法,有「通用解題方法」的美稱。
若用回溯法求問題的所有解時,要回溯到根,且根結點的所有可行的子樹都要已被搜尋遍才結束。
而若使用回溯法求任乙個解時,只要搜尋到問題的乙個解就可以結束。
(1)針對所給問題,確定問題的解空間:
首先應明確定義問題的解空間,問題的解空間應至少包含問題的乙個(最優)解。
(2)確定結點的擴充套件搜尋規則
(3)以深度優先方式搜尋解空間,並在搜尋過程中用剪枝函式避免無效搜尋。
(1)問題框架
設問題的解是乙個n維向量(a1,a2,………,an),約束條件是ai(i=1,2,3,…..,n)之間滿足某種條件,記為f(ai)。
(2)非遞迴回溯框架
int a[n],i;初始化陣列a;
i = 1;
while (i > 0(有路可走) and(未達到目標)) // 還未回溯到頭
if (i > n) // 搜尋到葉結點(3)遞迴的演算法框架else // 處理第i個元素
a[i]第乙個可能的值;
while (a[i]在不滿足約束條件且在搜尋空間內) 22: else 23: {
清理所佔的狀態空間; // 回溯25: i = i –1;
回溯法是對解空間的深度優先搜尋,在一般情況下使用遞迴函式來實現回溯法比較簡單,其中i為搜尋的深度,框架如下:
int a[n];try ( int i)if(i > n)
輸出結果;
elsefor( j = 下界 ; j <= 上界 ; j=j+1)
if( fun(j) )
a[i] = j;
try ( i + 1)
回溯前的清理工作(如 a[i] 置空值等);
回溯演算法以及剪枝問題理解
程式呼叫自身的程式設計技巧稱為遞迴。舉例說明一下 public void recursion int n 當n 2的時候首先執行recursion 2 接著執行recursion 1 最後結果就是1和2。遞迴的呼叫實質就像是乙個堆疊,當我們執行recursion 2 的時候發現無法得到結果並且接著執...
遞迴與回溯的理解
遞迴是什麼?求解問題 f 6 由於 f 6 n f 5 所以 f 6 需要拆解成 f 5 子問題進行求解,同理 f 5 n f 4 也需要進一步拆分,直到 f 1 這是 遞 f 1 解決了,由於 f 2 2 f 1 2 也解決了,f n 到最後也解決了,這是 歸 所以遞迴的本質是能把問題拆分成具有相...
優美的排列 加深對回溯演算法層數的理解
leetcode 優美的排列 假設有從 1 到 n 的 n 個整數,如果從這 n 個數字中成功構造出乙個陣列,使得陣列的第 i 位 1 i n 滿足如下兩個條件中的乙個,我們就稱這個陣列為乙個優美的排列。條件 第 i 位的數字能被 i 整除 i 能被第 i 位上的數字整除現在給定乙個整數 n,請問可...