資料結構之回溯

2022-08-31 10:42:13 字數 1952 閱讀 6222

利用回溯演算法求解八皇后問題

八皇后問題(eight queens problem)是國際西洋棋棋手馬克斯·貝瑟爾於2023年提出:在8×8格的西洋棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法。可以把8皇后問題擴充套件到n皇后問題,即在nxn的棋盤上擺放n個皇后,使任意兩個皇后都不能處於同一行、同一列或同一斜線上。

#include

#include

using namespace std;

int place(int k,int x)

{for(int i=0;i=0)

{x[k]++;

while(x[k]

可能這麼說不是很容易懂,咱們來的例項吧,那就是經典的0-1揹包問題,關於這一問題後邊很多演算法都會涉及到,咱們一點點深入~

我們還是使用典型的三揹包為例,問題描述如下:設有三個揹包,其重量分別為:16,15, 15;價值分別為: 45,25,25;請選擇揹包,使其重量不超過30,但價值最大。

可以看出我們的約束條件為總重量不超過30,目標是價值最大,那我們就可以使用回溯法的思想來求解:

每個揹包都可以被選擇中或者不選,理論上如果不加任何限制的話一共有八種可能(2×2×2),但我們在搜尋的過程中要時刻注意總重量不可超過30 ,在這個基礎上使其總價值最大,於是我們可以從第乙個揹包開始,先選中它,其重量是16,小於30,沒有問題,然後在選擇第二個揹包,其重量為15,二者總重量為31,超過30,所以不能選擇第二個揹包,同理第三個揹包也不能選,也就是說在選中第乙個揹包的前提下,另外兩個揹包就都不能再選了,這是八種理論可能情況中的一種;以此類推,不選第乙個揹包,在此基礎上選擇第二個揹包,總重量為15,沒有問題,再選第三個,此時總重量為30,也沒有問題;對照這兩種情況,前者總價值為45,後者總價值為50,當然,我們以上帝視角可以看出最大價值也就是50,但落實到具體的演算法該如何全方位多角度深層次地解決這一問題呢?

我們來看乙個完全二叉樹結構圖:

對於上述的揹包問題,在此二叉樹結構中可以簡單地理解為:從a出發,往左子樹方向走說明選中了a,往右子樹方向走說明沒有選中a,即「左選右不選」,落實到上圖中就是1代表選中0代表未選中;我們上邊說道的第一種情況,即只選中第乙個揹包的情況對應上圖的a->b->e->k;那這裡有朋友可能會問了為啥二叉樹會有四層,不是一共三個揹包嘛,對的,因為我們每一層所代表的揹包選與不選都得由下一層所決定,比如節點e代表第三個揹包,如果我們走到k就說明不選e,反之,若走到j則說明選中了e,因此三個揹包我們需要四層完全二叉樹,同理,若有n個揹包則需要n+1層。

總的來說,上述的求解過程在程式實現過程中可以這樣來理解:我們把二叉樹的每一層看成是某乙個物品。當我們選擇物品時總是從第乙個物品開始進行選擇,可能選,也可能不選。如果選中,則從二叉樹的左邊子樹開始搜尋,如果未選中,則從二叉樹的右邊子樹開始搜尋。以此類推即可~ 

如果設物品的重量存放在w陣列中, w[i]為第i個物品的重量,p[i]表示第i個物品的價值。c表示揹包能夠承受的最大重量。cw表示當前物品的重量,cp表示當前物品的價值(稍微記憶一下這幾個符號量的意義)。在選中情況下(即搜尋左子樹)執行下面的操作:     

( 1 )首先判斷加上該物品重量後是否滿足最大重量不超過c的要求,如果不超過,則:       cw+=w[i];       cp+=p[i];   反之則搜尋右子樹;  

( 3 )當搜尋到最後一層時,顯然可得到從根到該結點所選擇的所有物品的價值,如果該價值大於前一次得到的最大價值,則替代前一次的價值,反之,則不取代;    

執行上述語句的目的在於為訪問右子樹做準備。在訪問右子樹時,顯然不需要計算其重量和價值,因為右子樹表示未選中該物品

最後這幾步是我在一些資料中看到的...總感覺有問題,嘗試做了一些修改,還是有些彆扭,其實大家也可以理解,演算法這東西變幻莫測,再基本的原理也可以有很多表現形式,可以進一步優化,我們不要以上帝視角看待這個過程,這樣會想當然地人為進行條件約束;

資料結構之回溯思想

已知樓梯有20階台階,上樓可以一步上1階,也可以一步上2階。請編寫乙個程式,計算總共有多少種不同的上樓梯的方法。include stdio.h define max 20 定義20個台階的樓梯 int steps max steps i 等於1或者2,記錄第i步登上的台階數 int num 0 記錄...

資料結構與演算法之遞迴(回溯)

問題介紹 八皇后問題,是乙個古老而著名的問題,是回溯演算法的典型案例。該問題是國際西洋棋棋手馬克斯 貝瑟爾於1848年提出 在8 8格的西洋棋上擺放八個皇后,使其不能互相攻擊,即 任意兩個皇后都不能處於同一行 同一列或同一斜線上,問有多少種擺法。演算法思路分析 1 第乙個皇后先放第一行第一列 2 第...

回溯法基本思想 資料結構之簡單的回溯演算法

回溯演算法在資料結構中是一種常用的演算法,也是一種暴力求解法,基本思想是深度遍歷,選擇一條路一步一步走,當走不通的時候或者已經求得正確的結果,返回上一步,接著選擇另一條路走,直到遍歷完所有節點。回溯演算法是一種思想,真正用 實現的時候,大多時候都需要用的方法是遞迴。一.回溯演算法最出名的是8皇后問題...