回溯演算法 》應用

2021-06-07 23:15:51 字數 1723 閱讀 8172

回溯是一種系統地搜尋問題解答的方法。為了實現回溯,首先需要為問題定義乙個解的空間。而問題的解集合一般被組織成樹的形式(一般解所構成樹為邏輯樹不用去用**構建乙個解集合構成的樹)。然後以深度搜尋的方式去遍歷解集合,從而得到問題的解。可以使用限界函式來避免 對不可能求出解子集合的遍歷來優化回溯方法。

回溯方法求解的步驟:

1:定義乙個解的空間,它包含問題的解。

2:以適於搜尋的方式組織該空間,一般以一維陣列的形式組織成邏輯上的解空間樹(主要是滿二叉樹和排列數的形式)。

3:用深度優先法搜尋該空間,利用限界函式避免移動到不可能產生解的子空間。

回溯演算法可應用在貨箱裝船、揹包、最大完備子圖、旅行商、電路排列問題等,一般用來解決從解集合中對最優問題的求解。

在應用中由於候選解的數量都很大(指數級甚至大數的階乘級),而回溯法,在求解時間上大大減少。但其時間和空間複雜對還是相當奢侈的,在求解大規模問題中不是擁有「高富帥」配置的計算機玩的起的。對這些np問題的求解想得到多項式時間內「秒殺」,現在還是一種奢望。大都在指數級時間複雜度內。但在小規模問題中不失為一種好方法。回溯法的空間複雜度o(從開始節點起最長路徑長度)。

舉兩個例子觀摩一下,回溯法是怎麼把答案搜出來的。

乙個例子是貨箱裝船問題,它的解空間是以乙個一維陣列來構建乙個邏輯上的滿二叉樹。

問題場景:n 個貨箱,乙個貨船的載重量為c,wi是貨箱i的重量,且所有貨物之和大於c,求貨船最多裝多種的貨物。

假設n=4;w=[8,6,2,3],c=12;

按回溯法來分析問題,

1:構建解空間,有n個貨箱每個貨箱都有裝上船和不裝船兩種可能,所以n個貨箱就有2的n次方個解。這些解可組織成滿二叉樹的形式。如圖

邊權值為1表示貨物被裝上船,0便是貨物沒有裝上船。上面的二叉樹可以表示所有的解也就是解空間。

第i層的邊和第i個貨物對應,如果經過第i層,選擇的邊權值為1則第i個貨物被裝上船。從跟節點深度遍歷,每獲得乙個可行解,就與上一次獲得的解比較比上次的大則更新最優解。遍歷結束時就獲得了最後的解。

**如下:    

templatevoid maxloading(t w,t c,int n);

templateclass loading

private:

void maxloading(int i);

void maxloading1(int i);

int n;//貨物數量

t* w;//貨物重量的陣列

t r;//剩餘貨物重量

int* x;//記錄當前搜尋路徑下的裝載情況

int* bestx;//記錄最優裝載的貨物編號

t c;//貨箱的容量

t cw;//當前重量

t bestw;//最優重量

};templatevoid loading::maxloading(int i)

if(cw+w[i]void loading::maxloading1(int i)

r-=w[i];

if(cw+w[i]<=c)

if(cw+r>bestw)

r+=w[i];

}templatevoid maxloading(t w,t c,int n)

maxloading和maxloading1的區別加了限制條件,並可以獲得裝載貨物的編號。

(有錯誤還望指正)

回溯法 演算法框架及應用

在包含問題的所有解的空間樹中,按照深度優先搜尋策略,從根節點出發搜尋解空間樹。活結點 自身已生成但其孩子結點沒有全部生成的結點 擴充套件結點 指正在產生孩子結點的結點,e結點 死結點 指其所有結點均已產生的節點 首先根節點成為活結點,同時也成為當前的擴充套件結點 在當前的擴充套件結點處,搜尋向縱深方...

回溯 leetcode回溯演算法

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

深度優先遍歷回溯演算法的應用

void search int cur 這個模板就是目前我遇見的最簡潔的模板,用乙個二維陣列vis 3 其中vis 0 i 表示列,vis 1 i 和vis 2 i 表示對角線。因為 x,y 的y x值標識了主對角線,x y值標識了副對角線。由於y x可能為負,所以訪問時要加上n。下面主要介紹一下主...