0/1揹包問題

1.  蠻力法

僞代碼:

輸入:重量{W1,W2,----Wn},價值 {V1,V2,---Vn},揹包容量C
輸出:裝入揹包的物品編號和最大價值

1. 初始化最大價值maxValue=0;結果子集S=Φ;
2. 對集合{1,2,---,n}的每個子集T,執行下述操作;
   2.1 初始化揹包的價值value=0;揹包的重量weight=0;
   2.2 對子集T的每一個元素;
       2.2.1 如果weight+Wj<C,則weight=weight+Wj;value=value+Vj
       2.2.2 否則,轉步驟2考察下一子集
3. 輸出子集S中的各元素和最大價值maxValue;

 算法效率:Ω(2^n)

 

2.  動態規劃法

算法實現:

int KnapSack(int w[],int v[],int n,int C)
{
    int i,j;
    for(i=0; i<=n; i++) // 初始化第0列
        V[i][0]=0;
    for(j=0; j<=C; j++) // 初始化第0行
        V[0][j]=0;
    //計算第i行,進行第i次迭代
    for(i=1; i<=n; i++)
        for(j=1; j<=C; j++)
            if(j<w[i])
                V[i][j]=V[i-1][j];
            else
                V[i][j]=max(V[i-1][j],V[i-1][j-w[i]]+v[i]);
    // 求裝入揹包的物品
    for(j=C, i=n; i>0 ;i--)
    {
        if(V[i][j]>V[i-1][j])
        {
            x[i]=i;
            j=j-w[i];
        }
        else 
            x[i]=0;
    }
    return V[n][C]; //返回揹包取得的最大價值
}
/* 
    設n個物品的重量存儲在數組w[n]中,價值存儲在數組v[n]中;
    揹包的容量爲C,數組V[n+1][C+1]存放迭代結果,其中V[i][j]表示前i個物品裝入容量爲j的揹包中獲得的                
    最大價值,數組x[n]存儲裝入揹包的物品
*/

時間複雜性:O(n*C);

 

3. 分支限界法

僞代碼:

輸入: 重量{W1,W2,----Wn},價值 {V1,V2,---Vn},揹包容量C
輸出: 揹包獲得的最大價值和裝入揹包的物品

1. 根據限界函數計算目標函數的上界up;採用貪婪法得到下界down;
2. 根據根結點的目標函數值並加入待處理結點表PT;
3. 循環直到某個葉子節點的目標函數值在表PT中取得的最大值
   3.1 i=表PT中具有最大值的結點;
   3.2 對節點i的每個孩子結點x執行以下操作:
       3.2.1 如果結點x不滿足約束條件,則丟棄該節點;
       3.2.2 否則估算結點x的目標函數值lb,將結點x將入表PT中;
4. 將葉子結點對應的最優值輸出,回溯求得最優解的各個分量.



/* 
    設n個物品的重量存儲在數組w[n]中,價值存儲在數組v[n]中;
    揹包的容量爲C,數組V[n+1][C+1]存放迭代結果,其中V[i][j]表示前i個物品裝入容量爲j的揹包中獲得的                
    最大價值,數組x[n]存儲裝入揹包的物品
*/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章