回溯法解决01背包问题
生活随笔
收集整理的這篇文章主要介紹了
回溯法解决01背包问题
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
回溯法
問題的關(guān)鍵在于如何定義問題的解空間,轉(zhuǎn)化成樹(即解空間樹)。
只要是解可以描述成向量方式的,就可以使用回溯法,不斷的擴張部分向量,向下深入的過程就是,從部分解到可行解的過程。
解必須滿足多米諾性質(zhì):
可行解滿足約束–>部分解滿足約束
逆否為:部分解不滿足約束–>可行解不滿足約束
這樣可以用來pruning。
最簡單的回溯,解空間為二叉樹,又叫子集樹
遞歸方式實現(xiàn)的框架如下:
void backtrack(int t){ if(t > n) output(x); else{ for(int i = f(n,t); i <= g(n,t);i++){ x[t] = h(i); if(constraint(t) && bound(t)) backtrack(t+1); } } }實現(xiàn)代碼如下:
def pack_01_back(N,V,C,W):BestResult = [0]*Nx = [0]*NBestValue = [0]CurCost = [0]CurValue = [0]def pack_01_back_tracking(depth):# 遞歸出口if depth > N-1:if CurValue[0] > BestValue[0]:BestValue[0] = CurValue[0]# x為可行解,在葉子處把可行解記錄下來BestResult[:] = x[:]print BestResultprint BestValue# 注意else的含義else:for i in range(2):x[depth] = iif i == 0:pack_01_back_tracking(depth+1)else:if CurCost[0] + C[depth] <= V:CurCost[0] += C[depth]CurValue[0] += W[depth]pack_01_back_tracking(depth+1)# 回溯時的處理,就是往上回溯時,要把吃進去的吐出來CurCost[0] -= C[depth]CurValue[0] -= W[depth]pack_01_back_tracking(0)return BestResult,BestValue迭代方式實現(xiàn)
順序執(zhí)行流程圖如下
代碼如下
注意不剪枝,回溯是在最底部,回溯到最后放入的那個物品
#%% def pack_01_back_iteration2(N,V,C,W):depth = 0 BestResult = [False]*NSelected = [False]*(N)BestValue = 0CurCost = 0CurValue = 0 while True:if depth < N:if CurCost + C[depth] <= V:Selected[depth] = TrueCurCost += C[depth]CurValue += W[depth]# 回溯是處于底部 else:if CurValue > BestValue:BestValue = CurValue BestResult[:] = Selected[:]# 到底部時,已經(jīng)超了一個depth -=1while depth >= 0 and not Selected[depth]:depth -=1# 回溯到root退出if depth < 0:break# undoelse:Selected[depth] =FalseCurCost -= C[depth]CurValue -= W[depth]depth +=1return BestResult,BestValue#%% def pack_01_back_iteration(N,V,C,W):depth = 0BestResult = [False]*NSelected = [False]*(N)BestValue = 0CurCost = 0CurValue = 0while depth >= 0:while depth < N: if CurCost + C[depth] <= V:Selected[depth] = TrueCurCost += C[depth]CurValue += W[depth]depth +=1else:Selected[depth] = Falsedepth +=1if CurValue > BestValue:BestValue = CurValue BestResult[:] = Selected[:N]depth -=1while depth > 0 and Selected[depth] == 0:depth -=1if Selected[depth] ==1:Selected[depth] =FalseCurCost -= C[depth]CurValue -= W[depth]depth +=1if depth == 0:breakreturn BestResult,BestValue運行結(jié)果:
#%% N = 8 V = 30 C = [11,2,3,9,13,6,15,7,19] W = [5,2,5,7,5,11,6,14]print pack_01_back(N,V,C,W) print pack_01_back_iteration(N,V,C,W) print pack_01_back_iteration2(N,V,C,W)runfile('/root/test/back_tracking.py', wdir='/root/test') ([False, True, True, True, False, True, False, True], [39]) ([False, True, True, True, False, True, False, True], 39) ([False, True, True, True, False, True, False, True], 39)總結(jié)
以上是生活随笔為你收集整理的回溯法解决01背包问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Dijkstra和动态规划
- 下一篇: 01背包问题:回溯法和限界分支、递归和迭