演算法 貪心演算法(揹包問題)

2021-06-19 03:35:34 字數 1769 閱讀 2619

給定n

個物品和乙個容量為

c的揹包,物品

i的重量是

wi,其價值為

vi,揹包問題是如何選擇入揹包的物品,使得裝入揹包的物品的總價值最大,注意和

0/1揹包的區別,在揹包問題中可以將物品的一部分裝入揹包,但不能重複裝入。

用貪心法求解揹包問題的關鍵是如何選定貪心策略,使得按照一定的順序選擇每個物品,並盡可能的裝入揹包,知道揹包裝滿。至少有三種看似合適的貪心策略。

選擇價值最大的物品,因為這可以盡可能快的增加揹包的總價值,但是,雖然每一步選擇獲得了揹包價值的極大增長,但揹包容量卻可能消耗的太快,使得裝入揹包的物品個數減少,從而不能保證目標函式達到最大。

選擇重量最輕的物品,因為這可以裝入盡可能多的物品,從而增加揹包的總價值。但是,雖然每一步選擇使揹包的容量消耗的慢了,但揹包的價值卻沒能保證迅速的增長,從而不能保證目標函式達到最大。

以上兩種貪心策略或者只考慮揹包價值的增長,或者只考慮揹包容量的消耗,而為了求得揹包問題的最優解,需要在揹包價值增長和揹包容量消耗二者之間尋找平衡。正確的貪心策略是選擇單位重量價值最大的物品。

例如:有三個物品,其重量分別為

,價值分別為

,揹包的容量為

50,應用三種貪心策略裝入揹包的物品和獲得的價值如下圖所示:

設揹包容量為c,共有n個物品,物品重量存放在陣列w[n]中,價值存放在陣列v[n]中,問題的解存放在陣列x[n]中,貪心法求解揹包問題的演算法如下:

演算法:貪心法求解揹包問題

輸入:揹包的容量c,物品重量w[n],物品價值v[n]

輸出:陣列x[n]

改變陣列w和

v的排列順序,使其按單位重量價值

v[i]/w[i]

降序排列;

將陣列x[n]

初始化為0;

i=0;

迴圈直到(

w[i]>c

)    4.1   將第i

個物品放入揹包:

x[i]=1;

4.2    c=c-w[i];

4.3    i++;

x[i]=c/w[i]。

演算法的時間主要消耗在將各種物品按照單位重量的價值從大到小的排序,因此,其時間複雜性為o(nlog2n)

揹包問題與0/1揹包問題類似,所不同的是在選擇物品i(1)裝入揹包時。可以選擇一部分,而不一定要全部裝入揹包。揹包問題可以用貪心法求解,而0/1揹包問題卻不能用貪心法求解,下圖給出了乙個貪心法求解0/1揹包問題的示例。從下圖可以看出,對於0/1揹包問題,貪心法之所以不能得到最優解,是由於物品不允許分割,因此,無法保證最終能將揹包裝滿,部分閒置的揹包容量使揹包的單位重量價值降低了。事實上,在考慮0/1揹包問題時,應比較選擇該物品和不選擇該物品所導致的方案,然後再做出最優選擇,由此匯出許多相互重疊的子問題,所以,0/1揹包問題合適用動態規劃法求解。

實現函式knapsacks實現貪心法求解揹包問題,簡單起見,假設物品已按單位重量降序排列,演算法c++語言描述如下:

int knapsack (int w,int v,int n,int c)

; int maxvalue=0;

for(int i=0;w[i]

揹包問題(貪心演算法)

揹包問題 程式8 4 2.cpp 定義控制台應用程式的入口點。揹包問題 貪心演算法 include stdafx.h define maxnumber 20 typedef struct node object float find object wp,int n,float m i 0 while...

貪心演算法 揹包問題

詳細見原帖 我寫的是自己的感悟 揹包問題 有乙個揹包,揹包容量是m 150。有7個物品,物品可以分割成任意大小。要求盡可能讓裝入揹包中的物品總價值最大,但不能超過總容量。物品 a b c d e f g 重量 35 30 60 50 40 10 25 價值 10 40 30 50 35 40 30 ...

貪心演算法 揹包問題

貪心演算法 當前最優解 例如在刪除數的乙個例子中,乙個長度不大於240位的整數中,隨機刪除n個數,要求使得剩餘的數 從左到右的,組成乙個最小的整數 貪心步驟 例如 乙個數 1457326 n 4 1 找到當前最大的數 7 刪除 145326 2 找到當前最大的數 6 刪除 14532 3 找到當前最...