【软考】动态规划之01背包问题

来源:互联网 发布:金融软件行业 编辑:程序博客网 时间:2024/05/01 03:44

    最近学习软考,其中算法这遇到01背包问题,经过一番探索,终于通过资料来了解了一些,有了一些头绪,下面咱们一起看看学习下:


    首先解释下什么是01背包问题:给定一组共n个物品,每种物品都有自己的重量wi, i=1~n和价值vi, i=1~n,在限定的总重量(背包的容量C)内,如何选择才能使得选择物品的总价值之和最高。选择最优的物品子集放置于给定背中,最优子集对应n元解向量(x1,…xn), xi∈{0或1}(每种物品仅有一件,只有放或者不放这两种情况),因此命名为0-1背包问题。


     01背包问题具体例子:假设现有容量10kg的背包,另外有3个物品,分别为a,b,c,d,e。物品a重量为2kg,价值为6;物品b重量2kg,价值为3;物品c重量为6kg,价值为5,物品d重量为5kg,价值为4,物品e重量为4kg,价值为6。将哪些物品放入背包可使得背包中的总价值最大?


     欲求背包能够获得的总价值,即欲求前i个物体放入容量为m(kg)背包的最大价值c[i][m]——使用一个数组来存储最大价值,当m=10,i取3时,即原始问题了。而前i个物体放入容量为m(kg)的背包,又可以转化成前(i-1)个物体放入背包的问题。

 下面使用数学表达式描述它们两者之间的具体关系。


  表达式中各个符号的具体含义。


  w[i] :  第i个物体的重量;


  p[i] : 第i个物体的价值;


  c[i][m] : 前i个物体放入容量为m的背包的最大价值;


  c[i-1][m] : 前i-1个物体放入容量为m的背包的最大价值;


  c[i-1][m-w[i]] : 前i-1个物体放入容量为m-w[i]的背包的最大价值;


  由此可得:


      c[i][m]=max{c[i-1][m-w[i]]+pi , c[i-1][m]}

    

    

    当您能通过找规律手工填写出上面这张表就算理解了01背包的动态规划算法。
首先要明确这张表是至底向上,从左到右生成的。


    具体了解一下图:用e1单元格表示e行1列的单元格,这个单元格的意义是用来表示只有物品e时,有个承重为1的背包,那么这个背包的最大价值是0,因为e物品的重量是4,背包装不了。依次类推--当背包承重为2时,a和b可以放进去一个,价值不同,但是c,d,e还是不能放,重量都超过了2!


    每一列中单元格中的数表示最大的总价值,自底向上只要能得到最大价值就改变相应的总价值。例如,背包承重为6的列,自底向上,重量依次4,5,6,2,2,但是价值在重量等于4时,最高为6,再向上有一个重量为2的价值是6,这样就要改变,改成4+2正好等于背包的承重量,因此价值变成12。

     

    对于承重为8的背包,a8=15,是怎么得出的呢?根据01背包的状态转换方程,需要考察两个值:

   一个是f[i-1,j],对于这个例子来说就是b8的值9,另一个是f[i-1,j-Wi]+Pi


    f[i-1,j]表示我有一个承重为8的背包,当只有物品b,c,d,e四件可选时,这个背包能装入的最大价值;


    f[i-1,j-Wi]表示我有一个承重为6的背包(等于当前背包承重减去物品a的重量),当只有物品b,c,d,e四件可选时,这个背包能装入的最大价值f[i-1,j-Wi]就是指单元格b6,值为9,Pi指的是a物品的价值,即6由于f[i-1,j-Wi]+Pi = 9 + 6 = 15 大于f[i-1,j] = 9,所以物品a应该放入承重为8的背包

   

     01背包的四种解法详解:动态规划,贪心法,回溯法,优先队列式分支限界法(C语言编写)

   01背包问题吐血详解


0 0