1.1概述
在m件物品取出若干件放在空間為w的揹包裡,每件物品的體積為w1,w2……wn,與之相對應的價值為v1,v2……vn。最後選可行解中價值最大的解。
1.2問題分析
零一揹包問題不同於揹包問題,揹包問題的物件可分。
在解決揹包問題時,可以直接使用貪心法進行求解,思路也容易理解:先將物品的價效比進行排序,然後從高到低進行選取,保證選取的物品是當前最優選擇。由於物件可分得緣故,所以每一步都可行。因此每一步可行以及每一步的最優達成了整個問題的最優(貪心法的使用需要證明)。
回到零一揹包問題,它不具有貪心的特徵。不能直接使用貪心演算法,對比揹包問題,01揹包問題僅僅是缺少了並不是每一步選取都可行的特性,但他仍然滿足可行的區域性最優解就是全域性最優解。因此,只需要在貪心的實現上加入回溯,不可行則回溯。
1.3零一揹包問題的**
零一揹包問題的名字也體現了他的特徵,選擇結果只有0和1。
利用這種思想,可以將問題看作一棵樹,每乙個為物品都為乙個解點,每個節點都有兩個選擇:0或1,也就是選與不選
最後一層為所有答案的集合,未必都是可行解,但可行解一定在其中。如果暴力求解,時間複雜度為2^n。
2.1分支限界法的概述
分支限界法常以廣度優先或以最小耗費(最大效益)優先的方式搜尋問題的解空間樹。
在分支限界法中,每乙個活結點只有一次機會成為擴充套件結點。活結點一旦成為擴充套件結點,就一次性產生其所有兒子結點。所以在解決類似問題時,需要加入優先佇列或者棧的操作,來儲存元素。
分支限界法的思想可以簡單理解為:貪心演算法+回溯演算法+權值
2.2分支限界法解決01揹包問題
根據問題特性和演算法特性做如下操作:
1、首先需要將性價價效比進行排序。
對物品的選取順序為高價效比到底價效比,這就保證了每一步為最大的價效比。
2、為了保證每一步的選取都可行,需要構造限界函式。
當前操作是否可行,當前物品的質量,是否已經大與揹包剩餘容量的判斷
3.每次在進行選取後,到底該往哪邊走的判斷,這裡加入權值ub。
ub:當權選擇後的價值上限 ub=當前價值+剩餘質量*未裝入物品的最大價效比
2.3操作總結
分支限界法就是貪心和回溯的結合,再往前說就是是暴力求解的優化。將不能使用貪心求解的問題,加入限界函式。這裡加入的權值,目的是為了能夠在選取後能更好的選擇方向。不加入權值也行,直接規定:每次深度優先樹時,優先左子樹,或者右子樹。
2.4使用的資料結構和構造的類
在遍歷樹的過程中,需要儲存樹的節點,每個節點有自己的層數,在有全權值的情況下,每個節點有自己的權值,也就是訪問的順序,這裡需要使用優先佇列或者棧,使用棧時需要在進棧操作上進行選擇。
構造的類:1.物品類,將物品的屬性資訊都加入其中
構造物品
2.棧的節點類
構造佇列節點
3.1問題:0/1揹包問題。假設有4個物品,其重量分別為(4, 7, 5,3), 價值為(40, 42, 25, 12),揹包容量w=10。首先,將物品按單位重量價值從大到小排序,結果如下:
物品
重量(w)
價值(v)
價值/重量(v/w)14
401027
42635
25543
1243.2執行樹
if (nweelement2==null)//優先左邊
else if(nweelement1.ub<=nweelement2.ub)
else }}
private void fuzhi(int v, int w){
weights=new weight[v.length];
for(int i=0;i0 && weights[key-1].p執行結果圖:
分支限界法解決0 1揹包問題
0 1揹包問題我們已經說過很多次了,這次是用最近學的分支限界法解決。分支限界法就是利用佇列或者優先佇列在儲存解空間樹的活結點,並每次彈出乙個作為擴充套件結點,是一種廣度優先遍歷,區別於回溯法的深度優先遍歷。而優先佇列時間複雜度更低,因為我們每次加入乙個活結點時,佇列都會排序,所以我們出隊的結點一定是...
分支限界 回溯法解決01揹包問題
分支限界法 分支限界搜尋,以廣度優先或最小耗費優先的方式搜尋解空間。這裡直接是用的fifo。其選擇下一擴充套件結點的策略是 在每乙個活結點處,計算乙個函式值 限界 並根據函式值,從當前活結點表中選擇乙個最有利的結點作為擴充套件結點,使搜尋朝著解空間上有最優解的分支推進,以便盡快地找出乙個最優解。針對...
0 1揹包問題 分支限界法
0 1揹包問題可描述為 n個物體和乙個揹包。對物體i,其價值為value,重量為weight,揹包的容量為w 如何選取物品裝入揹包,使揹包中所裝入的物品總價值最大?2.1 用到的資料結構 class goods 定義貨物資料型別 class knapsack 揹包 2.2 演算法步驟1 定 空間。x...