對回溯法的理解:
回溯法本質就是深搜,對所有可能的結果進行搜索匹配,由於很多情況下結果很多,就需要進行適當的剪枝和分界限制來加快得到解。
回溯法用的最多的就是遞歸,其實也可用遞推,但是遞歸比較符合人類邏輯
。
回溯法的解題通常是有模板的:
Void backtrack()
{
If(到達邊界)
{輸出答案/記錄答案}
Else{ 記錄這個點,現存結果更新,遞歸,現存結果還原,取消該點記錄}
}
回溯法的有三種情況:
1):找所有可能解:通過一個結果數組記錄搜索得到的解,然后再到達邊界時輸出
2):尋找其中過一個的解 : 同上;
2):尋找最優 (選和不選) 在邊界點記錄/更新最優值 + 在else中除了要對選取這個點的結果進行搜索還要對忽略這個點的結果進行搜索
回溯法的常用剪枝:
1) :判斷該點在之后的所有點組合起來能不能到達最優或者超過當前最優。不能就剪枝
2)當前點是不是訪問過,訪問過忽略
2) 加上當前點是不是會越過限制條件,是的話剪枝
3) 如果只要求輸出一個解,設立一個flag,有了一個答案之后設置flag為1,當flag為1時,全部return
子集和問題的解空間結構和約束函數:
假設給定集合 C = { x1,x2,x3 ……… xn}; 給定正整數P
解空間結構 C’ ={ xi,..xk} (1<=i<k<=n)
約束函數:
1:假設當前的搜索點為 Xi ((1<=i<n)),如果 {Xi+1 ,Xi+2,Xi+3………Xn}的和小於P,說明這個這個點取了也沒用,剪枝;如果大於說明接下來的有可能得到P,那就繼續搜索
2: 如果當前點大於P,該點不取
3: 如果當前點加上當前總和結果大於P,不取
本章學習遇到的問題:
主要是剪枝不充分,導致算法超時問題.
結對編程中問題:
主要是背包問題的剪枝,要按照嚴格限界,不然會超時。
這個限界也是之前沒有用過限界函數.下面總結一下這個限界函數:
首先先要把數組進行降序排序,預測當前背包剩余容量最大可以裝下多少價值的物品
如果剩余容量能夠能夠承載的最大價值 + 當前的背包價值 大於 當前的最優值,說明這個點可以繼續搜索下去。小於,說明,如果裝入這個物品,那么背包的剩余容量所能容納的最大價都不能超過之前的最優值,說明該點不必取。
之所以先降序排序,是為了通過貪心算法判斷上界,盡可能的取最大的。