0/1背包问题之动态规划法求最优解和最优解路径
一、问题介绍
给定 n 种物品和一个容量为 C 的背包,物品 i 的重量是 wi,其价值为 vi。问:应该如何选择装入背包的物品,使得装入背包中的物品的总价值最大?
二、问题分析
面对每个物品,我们只有选择拿(1)取或者不拿(0)两种选择,不能选择装入某物品的一部分,也不能装入同一物品多次。
把物品随机排成一排,标记为1、 2、 3……,从1号物品开始依次判断是否装包,面对当前物品有两种情况:
- 该物品的重量大于背包的容量,装不下,只能选择不装
- 该物品的重量小于背包的容量,可以装下,但是否要装,需要进一步判断,因为可能存在这样一种情况:要装该物品,就必须拿出之前装的一个物品,而这时可能会出现如下不同情况:
2.1 【拿掉之前的一个物品并装进当前物品后 背包的总价值】<【不拿掉之前的物品且不装当前物品 背包的总价值】 ;
2.2 【拿掉之前的一个物品并装进当前物品后 背包的总价值】>【不拿掉之前的物品且不装当前物品 背包的总价值】
举例说明:有2个物品,重量数组w={7,6},价值数组v={3,9},背包容量为8。1号物品重量7小于背包容量8,放进背包,此时背包价值为3,到2号物品时,2号物品重量3也小于背包容量8,但是如果要把2号物品放进背包,就要把1号物品从背包中拿出,此时就要比较两种情况下背包的价值哪个更大,max(2号物品不放进背包,2号物品放进背包(隐含着要把1号物品取出背包))=max(3,9)=9,因此选择拿出1号物品,放进2号物品。
当然背包容量也有可能不用取出之前的物品可以直接放下当前物品,此时肯定是放要比不放价值更大。
因此,当物品重量小于背包总容量,也就是背包可以装下该物品时,要判断装之前和装之后背包的总价值来决定是否要装该物品。
因此,通过判断当前物品是否装包而计算当前问题的最优解时,是要用到上一个子问题的最优解的(通过判断上一个物品是否装包而计算得到),也就是说,如果当前物品不装进背包,那么上一个子问题的最优解就是当前状态的最优解,如果当前物品装包后的价值大于不装的价值,那么当前问题的最优解就是当前物品装进背包后产生的价值,这个值=上一个子问题中背包容量为【背包总容量减去当前物品重量】的情况下的最优解+当前物品价值。总之,当前问题的最优解求解过程依托于上一个子问题的各个状态下的最优解,所以在求当前问题的最优解之前要先求出之前的所有情况下的最优解。也就是要先求子问题的最优解。这里就需要用到动态规划的方法。
三、动态规划(DP)
动态规划(Dynamic Programming,DP) 与分治法的区别在于划分的子问题是有重叠的,解过程中对于重叠的部分只要求解一次,记录下结果,减少了重复计算过程。
另外,DP在求解一个问题最优解时,不是固定的计算合并某些子问题的解,而是根据各子问题的解的情况选择其中最优的。
动态规划求解具有以下性质:
最优子结构性质:最优解包含了其子问题的最优解,不是合并所有子问题的解,而是找最优的一条解线路,选择部分子最优解来达到最终的最优解。
子问题重叠性质:先计算子问题的解,再由子问题的解去构造问题的解(由于子问题存在重叠,把子问题解记录下来为下一步使用,这样就可以从备忘录中读取)。其中备忘录先记录初始状态。

本文详细解析了0/1背包问题的动态规划求解方法,包括最优解和最优解路径的求解过程。通过实例演示了如何利用二维数组记录状态,以及如何通过递归和非递归方式回溯最优解路径。
4万+

被折叠的 条评论
为什么被折叠?



