您的位置:首页 > 其它

动态规划求解01背包相关的基本问题

2012-04-29 22:56 387 查看
背包问题是经典问题,网上已经提供了很多优秀的解法,这里摘录动态规则的方法,同时顺便把背包相关的变形问题也一些阐述。

问题:

1. 经典背包问题:给定一个载重量为m,n个物品,其重量为wi,价值为vi,1<=i<=n,要求:把物品装入背包,并使包内物品价值最大。

2. 变形:要求装入的物品重量最大?(问题很简单,但请先别BS我)

3. 变形:要求装入的物品重量刚好等于背包的承重?换一种说法就是:N个数里挑出任意个数,使这些数的和等于某个值M。

4. 变形:N个数里挑出任意个数,使这些数的和最接近M,即和与M的差的绝对值最小。

问题1请参考:http://blog.csdn.net/livelylittlefish/article/details/2186206#

核心思想如下:

在0/1背包问题中,物体或者被装入背包,或者不被装入背包,只有两种选择。

循环变量i,j意义:前i个物品能够装入载重量为j的背包中
(n+1)*(m+1)数组value意义:value[i][j]表示前i个物品能装入载重量为j的背包中物品的最大价值
若w[i]>j,第i个物品不装入背包
否则,若w[i]<=j且第i个物品装入背包后的价值>value[i-1][j],则记录当前最大价值(替换为第i个物品装入背包后的价值)

问题2:很简单。可以将这里的重量看成是问题1的价值。之所以写出来是为了方便分析问题4.

问题3:采用类似于问题1的方法,对N个数(无序),以N[i]表示第i个数。构造一个(N+1)行(M+1)列的矩阵(+1行与列是为了下标好计算)。

关键点:对于某个M=j。给定序列N[1~i],组成和为 j 的子集U中若包含N[i],则N[1~i-1]肯定能够组成和为j-N[i]。

如图所示,为了简单起见,令N个数正好是1到N递增(不需要是有序的,仅为举例方便),令M=6。

矩阵的值V[i][j]有三种表示方法:

1. Y。表示N[i] = j。这样,由N[1~i]个数,和为j的一种挑法就是只挑出N[i]本身。

2. X。表示由N[1~i]个数构成和为j的集合中,任一集合都没有N[i] 。

3. 矩阵的另一个地址,表示N[i] 可以构成和为j的集合中的一个元素,而其它的元素需要到矩阵的另一个地址中继续寻找。

算法描述如下:

1. 若当前N[i]=j ,则V[i][j]标记为 “Y”;

2. 判断N[i]是否属于加和集合。需要看N[1~i-1]是否可以构成 j-N[i]。判断的方法就是对第j-N[i]列,从行号为i-1开始直到0,看是否有值不为 “X”。查找的结果有两种可能:

a. 没有,即全为X。表示N[i]不可能属于加和集合中的一分子,故把V[i][j]标记为 “X”;

b. 有。记录转转地址。

当遍历结束后。采用回溯可以得到所有构成的路径。这时,标记为“Y”的矩阵值即是路径回溯的终点。

N个数\M

0
1
2
3
4
5
6
0
Y
X
X
X
X
X
X
1
X
Y
X
X
X
X
X
2
X
X
Y
(1,1)
X
X
X
3
X
X
X
Y
(1,1)
(2,2)
(2,3)
4
X
X
X
X
Y
(1,1)
(2,2)
5
X
X
X
X
X
Y
(1,1)
举例分析:

初始化第0行与第0列。

看v[1][1],由于有N[1]=1,故标记为Y。

看v[2][3],考虑N[2]=2是否是构成和为3的一个元素,则需要看由元素集合N[1~i-1],是否可以构成j-N[i],即{1}是否可以构成和为1。从查找v[1][1]找到v[0][1],发现v[1][1]标记为Y,表示可以构成,所以v[2][3]记录地址{1,1}。

看v[3][6],同理,若N[3]=3能构成和为6的一个元素的话,就要求N[1~2]能构成和为3,查找发现v[2][3]的值不是“X”,表示上述假设成立,因此记录(2,3).

当遍历结束后,回溯寻找和为M的方法,这里M=6.

首先发现v[5][6],确定5,跳转到v[1][1],为Y,结束,集合为{1,5}. 同列往上继续走到v[0][1],为X,结束。

往上走到v[4][6], 确定4,跳转到v[2][2],为Y,结束,集合为{2,4}. 同列往上继续走到v[1][2]与v[0][2],皆为X,结束。

往上走到v[3][6],确定3,跳转到v[2][3],确定2,跳转到v[1][1],确定1,集合为{1,2,3}. 同列往上继续走到v[0][1],为X; 回退,发现v[1][3]也为X,结束。

往上走到v[1~2][6],都没有构成集合,结束。

这里为什么在找到一条路径后,还需要继续在同列往上走呢?这是为把所有组合都成找到,请自行分析M=7的情况,如果不往上走,将只能找到{2,5}与{3,4},而少一组{1,2,4}.而最后一组{1,2}又构成了3.

问题4:

运用问题2或3的解法可解。运用问题2来解比较快:假设背包最大承重为M,解一次问题2,即可得到加和小于M,且最接近M的的值,设为S。由于求的是绝对值最小,所以有可能可以找到加和大于M的解,而这个解必然属于背包大小为M+1到M+(M-S)-1 范围内,问题2的解。举例如下:假设M=6,求得S=3,目前的绝对值差为3,而如果正确的解是S>M的情况,那么该解必然属于背包大小为7到8当中的最优解。即,最坏情况下,给一个大小为8的包,能装满,则这时和的绝对值差为2,比原来优,而背包给的再大已经没有意义。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: