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]存储装入背包的物品
*/

 

全部评论

相关推荐

不愿透露姓名的神秘牛友
昨天 20:55
阿里国际 Java工程师 2.7k*16.0
程序员猪皮:没有超过3k的,不太好选。春招再看看
点赞 评论 收藏
分享
11-05 07:29
贵州大学 Java
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务