演算法學習(一)回溯法

2021-09-25 23:09:12 字數 2578 閱讀 5411

回溯演算法實際上乙個類似列舉的搜尋嘗試過程,主要是在搜尋嘗試過程中尋找問題的解,當發現已不滿足求解條件時,就「回溯」返回,嘗試別的路徑。

回溯法是一種選優搜尋法,按選優條件向前搜尋,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術為回溯法,而滿足回溯條件的某個狀態的點稱為「回溯點」。

許多複雜的,規模較大的問題都可以使用回溯法,有「通用解題方法」的美稱。

在包含問題的所有解的解空間樹中,按照深度優先搜尋的策略,從根結點出發深度探索解空間樹。當探索到某一結點時,要先判斷該結點是否包含問題的解,如果包含,就從該結點出發繼續探索下去,如果該結點不包含問題的解,則逐層向其祖先結點回溯。(其實回溯法就是對隱式圖的深度優先搜尋演算法)。

若用回溯法求問題的所有解時,要回溯到根,且根結點的所有可行的子樹都要已被搜尋遍才結束。

而若使用回溯法求任乙個解時,只要搜尋到問題的乙個解就可以結束。

(1)針對所給問題,確定問題的解空間:首先應明確定義問題的解空間,問題的解空間應至少包含問題的乙個(最優)解。

(2)確定結點的擴充套件搜尋規則

(3)以深度優先方式搜尋解空間,並在搜尋過程中用剪枝函式避免無效搜尋。

//針對b+樹的遞迴回溯方法

void backtrack (int t)//初始條件

}

//針對n叉樹的迭代回溯方法

void iterativebacktrack ()

}} else //不存在子節點,返回上一層}}

所給的問題是從n個元素的集合s中找出滿足某種性質的子集時,相應的解空間成為子集樹。

如0-1揹包問題,從所給重量、價值不同的物品中挑選幾個物品放入揹包,使得在滿足揹包不超重的情況下,揹包內物品價值最大。它的解空間就是乙個典型的子集樹。

此類題型基本正規化:

void backtrack (int t)}}

leetcode例題:子集

給定一組不含重複元素的整數陣列 nums,返回該陣列所有可能的子集(冪集)。

說明:解集不能包含重複的子集。

輸入: nums = [1,2,3]

輸出:[

[3],

[1],

[2],

[1,2,3],

[1,3],

[2,3],

[1,2],

]

class solution 

helper(nums,0,new arraylist<>()); //從0個數開始直到n個數的排列

return listall;

}public void helper(int nums,int k,listlist) }}

所給的問題是確定n個元素滿足某種性質的排列時,相應的解空間就是排列樹。

leetcode例題:括號生成

給出 n 代表生成括號的對數,請你寫出乙個函式,使其能夠生成所有可能的並且有效的括號組合。

例如,給出 n = 3,生成結果為:

[

"((()))",

"(()())",

"(())()",

"()(())",

"()()()"

]

class solution 

void helper(string s,int l,int r,int n)

if (l < n) //左括號小於總數,可以放左括號

if (r < l) //右括號小於左括號數,可以放右括號}}

此類問題為排列樹問題,即n個元素的全排列的滿足條件子集,此類問題正規化如下

void backtrack (int t)

}

問題描述:八皇后問題是乙個以西洋棋為背景的問題:如何能夠在 8×8 的西洋棋棋盤上放置八個皇后,使得任何乙個皇后都無法直接吃掉其他的皇后?為了達到此目的,任兩個皇后都不能處於同一條橫行、縱行或斜線上。

1. a[0] ~ a[7]不能相同,儲存棋子所在的列

2. 同一對角線上即座標斜率為1,即(i,j)和(k,l)的位置,當|i-k|=|j-l| 時,兩個皇后才在同一條對角線上。

遞迴回溯:

int a = new int[n];  //儲存皇后位置的陣列,下標為行,值位列

void queen(int k,int n)

for (int i = 0;i < n;i++) }}

boolean isconflict(int k,int i)

}return true;

}

各種大神解法:

參考文章:

五大常用演算法之一 回溯法

熟悉演算法的朋友們都知道,我們經常使用五大演算法思想,分別是 1.貪心演算法 2.動態規劃 3.分治法 4.回溯法 5.分支限界法 今天,我們先來總結一下 回溯法 簡介 回溯法的思想如下 每次都沿著一條路去尋找結果,如果發生了無解的情況,則返回到上乙個分叉口,然後選擇另乙個選擇。再向下走到盡頭。回溯...

演算法入門(4) 回溯法

1 概念 回溯演算法實際上乙個類似列舉的搜尋嘗試過程,主要是在搜尋嘗試過程中尋找問題的解,當發現已不滿足求解條件時,就 回溯 返回,嘗試別的路徑。回溯法是一種選優搜尋法,按選優條件向前搜尋,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術...

演算法實驗4《回溯法》

1.編寫乙個簡單的程式,解決8皇后問題。include using namespace std bool backtrack int list 8 int t return false intmain 2.批處理作業排程問題 問題描述 給定n個作業的集合j j1,j2,jn 每乙個作業ji都有兩項任...