曾經研究過一個簡單的N皇后問題,對回溯法也有了個模糊的認識,大致理解就是:先一直做某件事,當完畢某個條件時或者是觸犯某個條件時。再返回到近期的一個類似還原點的地方。
在用回溯法求解0-1背包問題的時候。主要遇到三個相對難解決的問題:1。什么是界限函數;2,什么時候用它;3,回溯到哪兒。
什么是界限函數?
例如以下圖:
當我們身在一棵搜索空間樹中,站在一個K點舉棋不定的時候。我們能夠用它估算假設我們繼續向下走,我們走完本段路會獲得的總價值。
假設我們如今有一個最大解,當我用界限函數算出一個價值后和我當前的最大解比較。假設能獲得更大利益。我們選擇繼續向下走,假設不能。果斷放棄。
從下圖中的偽代碼能夠看出,我們計算后半段最大價值的時候。使用的還是一個貪心算法。盡管切割的情況是不被同意的,可是我們能夠用這個結果來進行估算。
回溯法得到的搜索空間樹:
什么時候使用界限函數?
數學一點兒的說法是:當X[i]=0時。
通俗一點說:當進入右結點的時候。
怎樣回溯的問題?
向上回溯到第一個不是0的結點(而且這個結點不是頂點)。
求解思路
如上圖搜索樹。在建立搜索樹之前,我將全部的物品依照V/W(價值重量比)從大到小排序。然后從第一個開始。依次向背包(背包大小110)中放入,放到第6個的時候,這時候發現6太大了,不能裝入了,這時候用界限函數推斷下,假設繼續下去。會獲得的最大價值,得出這個價值后,和上幾次查找得到的最大價值對照,可是由於我們在這之前還沒有獲得過別的解,所以界限函數再和最大價值的初值-1比較的時候,總是會選擇繼續。這樣我們就得到了一個解139.然后我們回溯到第一個X[i]不等於0的地方,此處為X[5],然后將X[5]置為0。這時候X[5]置0了,我們就先用界限函數推斷下X[6]到X[8]的情況,得出了個164.44,這個比我們上次得到的第一個解也是最大的解139大。說明向后繼續,肯會出現一個比139還大的解,所以我們選擇向后繼續。。
。。。
。
。。
。。。。。
。
。
但我們回溯到X[1]的時候。我們將X[1]置0。這時候用界限函數估算下物品2到物品8可能獲得的最大價值,發現是155.11,比我們實際得到的最大解159還小,然后果斷放棄,再向上回溯,發現這已經到了盡頭了,然后停止。
結合曾經的N皇后問題,N皇后問題是我一行一行的放皇后。假設當下一行放到最后一個位置的時候還是會產生攻擊。這時候我們就調整上一行皇后的位置,然后再回到本行從第一個開始放。對照0-1背包,這個是完畢一次求解過程,然后就回溯繼續求解。
所以,回溯法是先一直做,做不下去了,然后才向回走。
小結:
0-1背包問題的用回溯法解決最開始提出的三個問題挺關鍵的,試想,假設一個問題足夠大的話。用界限函數可以砍掉非常多不合條件的子節點。極大的提高了效率。