动态规划算法之0-1背包问题

我们首先来看一下问题:一个旅行者有一个容量为C的背包,现在有n种物品,每件的重量分别是W1、W2、……、Wn,每件物品的价值分别为V1、V2、……、Vn, 需要将物品放入背包中,要怎么样放才能保证背包中物品的总价值最大?具体数据如下表,其中n=4,C=8。

                                                     

前面已经对动态规划的基本概念做了详细的讲解,动态规划算法的核心是最优子结构边界状态转移方程式。现在我们来按这个思路对问题进行分析,分别找出以上三种。

算法分析

这里用F(N,W)表示前N个物品最佳组合对应的价值,W代表当前背包容量。

本题的最优子结构是考虑最后一种物品,即第四个。这里有两种情况,一个是第4种物品装入背包,则此时问题转化为前3种物品放入容量为C-W4的空间内,此时的背包最大值为F(3,8-W4)+V4;另外一种是不选择将第4种物品放入背包,则此时的问题是F(3,8)=F(4,8)。所以这里4种物品和3种物品最优选择之间存在这样的关系,即F(4,8)=Max(F(3,8),F(3,8-W4)+V4)。

现在我们来确定下问题的边界是什么。显然也有两种情况,用公式来表示。

当N=1,C>=W1时,F(N,W)= V1;

当N=1,C<W1时,F(N,W)=0。

整理一下就能得到问题的状态转移方程:

F(N,W)=0(N<=1,C<W1);

F(N,W)=V1(N==1,C>=W1);

F(N,W)=F(N-1,W)(N>1,C<Wn;

F(N,W)=Max(F(N-1,W),F(N-1,C-Wn)+Vn)(N>1,C>=Wn)。

到这里,利用动态规划求解问题的模型分析已完成,现在来看下怎么实现。

同样,我们这里对其进行一步步的填表,这里直接给出最后过程。


   1) 如N=1,W=1,w(1)=2,v(1)=3,有W<w(1),故F(1,1)=F(1-1,1)=0;

    2) 又如N=1,W=2,w(1)=2,v(1)=3,有W=w(1),故F(1,2)=max{ F(1-1,2),F(1-1,2-w(1))+v(1) }=max{0,0+3}=3;

    3) 如此下去,填到最后一个N=4,W=8,w(4)=5,v(4)=6,有W>w(4),故F(4,8)=max{ F(4-1,8),F(4-1,8-w(4))+v(4) }=max{9,4+6}=10;所以填完表如上图。



 表格填完,最优解即是F(N,C)=F(4,8)=10,但还不知道解由哪些商品组成,故要根据最优解回溯找出解的组成,根据填表的原理可以有如下的寻解方式:

    1) F(N,W)=V(N-1,W)时,说明没有选择第i 个商品,则回到F(N-1,W);

    2) F(N,W)=F(N-1,W-Wn)+Vn时,说明装了第i个商品,该商品是最优解组成的一部分,随后我们得回到装该商品之前,即回到F(N-1,W-Wn);

    3) 一直遍历到N=0结束为止,所有解的组成都会找到。

 如上例子,

    1) 最优解为F(4,8)=10,而F(4,8)!=F(3,8)却有F(4,8)=F(3,8-w4)+v4=F(3,3)+6=4+6=10,所以第4件商品被选中,并且回到F(3,8-w4)=F(3,3);

    2) F(3,3)=F(2,3)=4,所以第3件商品没被选择,回到F(2,3);

    3) 而F(2,3)!=F(1,3)却有F(2,3)=F(1,3-w2)+v(2)=F(1,0)+4=0+4=4,所以第2件商品被选中,并且回到F(1,3-w(2))=V(1,0);

    4) F(1,0)=F(0,0)=0,所以第1件商品没被选择。

 至此,此0-1背包问题已经解决。

 下面给出代码实现:

void FindMax()//动态规划
{
    int i,j;
    //填表
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=c;j++)
        {
            if(j<w[i])//包装不进
            {
                V[i][j]=V[i-1][j];
            }
            else//能装
            {
                if(V[i-1][j]>V[i-1][j-w[i]]+v[i])//不装价值大
                {
                    V[i][j]=V[i-1][j];
                }
                else//前i-1个物品的最优解与第i个物品的价值之和更大
                {
                    V[i][j]=V[i-1][j-w[i]]+v[i];
                }
            }
        }
    }
}
时间效率为O(n*c),由于用到二维数组存储子问题的解,所以动态规划的空间效率为O(n*c)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值