背包问题详解

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

对每一个确定的i(1≤i≤n),用一个表p[i]存储函数 ,j)的全部 ,用一个表 存储函数m(i, 的全部 对每一个确定的 存储函数 跳跃点。 可依计算m(i,j)的递归式递归地由表 的递归式递归地由表p[i+1]计算, 计算, 跳跃点。表p[i]可依计算 可依计算 , 的递归式递归地由表 计算 初始时p[n+1]={(0,0)}。 初始时 , 。
5 0 6 9 9 9 9
6 0 6 9 9 9 12
7 0 6 9 9 10 12
8 0 6 9 11 11 15
9 0 6 9 11 13 15
10 0 6 9 14 14 15
x1=1 x2=1 x3=0 x4=0 x5=1
ቤተ መጻሕፍቲ ባይዱ
0 0 0 0 0 0
1 2 3 4 5
11
1、0-1背包问题—动态规划算法 背包问题—
void Traceback(int **m, int w[ ], int c, int n, int x[ ]) {// 计算x for (int i=1; i<n; i++) if (m[i][c]==m[i+1][c]) x[i]=0; else { x[i]=1; c-=w[i]; } x[n]=(m[n][c])?1:0; }
动态规划系列之二 背包问题
彭智朝 2010.6.8
1
解空间
设Xi表示第i件物品的取舍,1代表取,0代表舍, 搜索的空间为n元一维数组(X1,X2,X3,……, Xn),取值范围为(0,0,0……,0,0), (0,0,0……,0,1),(0,0,0……,1, 0),(0,0,0……,1,1),……,(1, 1,1……,1,1)。
j ≥ wi max{m(i + 1, j ), m(i + 1, j − wi ) + vi } m(i, j ) = 0 ≤ j < wi m(i + 1, j )
j ≥ wn v n m(n, j ) = 0 0 ≤ j < wn
6
0-1背包问题
0/1背包问题可以看作是决策一个序列 1, x2, …, xn),对任 背包问题可以看作是决策一个序列(x 背包问题可以看作是决策一个序列 , 一变量x 的决策是决定x 还是 还是x 。在对x 决策后, 一变量 i的决策是决定 i=1还是 i=0。在对 i-1决策后,已确定了 (x1, …, xi-1),在决策 i时,问题处于下列两种状态之一: 问题处于下列两种状态之一: ,在决策x (1)背包容量不足以装入物品 ,则xi=0,背包不增加价值; )背包容量不足以装入物品i, ,背包不增加价值; (2)背包容量可以装入物品 ,则xi=1,背包的价值增加了 i。 )背包容量可以装入物品i, ,背包的价值增加了v 这两种情况下背包价值的最大者应该是对 决策后 决策后的背包 这两种情况下背包价值的最大者应该是 对 xi决策后的背包 价 值 。 令 V(i, j) 表 示 在 前 i(1≤i≤n) 个 物 品 中 能 够 装 入 容 量 为 j ( 1≤j≤C) 的背包中的物品的最大值 , 则可以得到如下动态规 ) 的背包中的物品的最大值, 划函数: 划函数:
多重背包问题
种物品和一个容量为V的背包。 种物品最多 有N种物品和一个容量为V的背包。第i种物品最多 n[i]件可用 每件费用是c[i] 价值是w[i] 件可用, c[i], w[i]。 有n[i]件可用,每件费用是c[i],价值是w[i]。求 解将哪些物品装入背包可使这些物品的费用总和不 超过背包容量,且价值总和最大。 超过背包容量,且价值总和最大。
4
其他类型背包问题
完全背包问题(0/1): 完全背包问题(0/1): (0/1)
种物品和一个容量为V的背包,每种物品都有无 有N种物品和一个容量为V的背包,每种物品都有无 件可用。 种物品的费用是c[i] 价值是w[i] c[i], w[i]。 限件可用。第i种物品的费用是c[i],价值是w[i]。 求解将哪些物品装入背包可使这些物品的费用总和 不超过背包容量,且价值总和最大。 不超过背包容量,且价值总和最大。
9 0 6 9 11 13 15
10 0 6 9 14 14 15
0 0 0 0 0 0
1 2 3 4 5
10
0 0
w1=2 v1=6 w2=2 v2=3 w3=6 v3=5 w4=5 v4=4 w5=4 v5=6
1 0 0 0 0 0 0
2 0 6 6 6 6 6
3 0 6 6 6 6 6
4 0 6 9 9 9 9
12
算法改进
的递归式容易证明, 由m(i,j)的递归式容易证明,在一般情况下,对每一个确定的 的递归式容易证明 在一般情况下, i(1≤i≤n),函数 是关于变量j的阶梯状单调不减函数 ,函数m(i,j)是关于变量 的阶梯状单调不减函数。跳跃 是关于变量 的阶梯状单调不减函数。 点是这一类函数的描述特征。在一般情况下,函数m(i,j)由其 点是这一类函数的描述特征。在一般情况下,函数 由其 全部跳跃点唯一确定。如图所示。 全部跳跃点唯一确定。如图所示。
5
0-1背包问题
设所给0-1背包问题的子问题 设所给 背包问题的子问题
max ∑ v k x k
k =i
n ∑ wk x k ≤ j k =i 算法复杂度分析: 算法复杂度分析: xk ∈ {0,1}, i ≤ k ≤ n
n
的递归式容易看出, 从m(i,j)的递归式容易看出,算法需要 , 的递归式容易看出 算法需要O(nc)计算 计算 的最优值为m(i,j),即m(i,,算法需要的计算时间较 的最优值为 , , 很大时 是背包容量为 可选择物品为i, , 是背包容量为j, 时间。当背包容量c很大时 j)是背包容量为 ,可选择物品为 , 时间。当背包容量 很大时, i+1,…,n时当c>2n时,算法需要 。由n)计算时间。 , 例如, 背包问题的最优值 , 时 背包问题的最优值。 0-1背包问题的最优子 背包问题的最优子 算法需要Ω(n2 计算时间 计算时间。 多。例如,0-1背包问题的最优值 结构性质,可以建立计算m(i,j)的递归式如下。 的递归式如下。 结构性质,可以建立计算 , 的递归式如下
7
1、0-1背包问题—动态规划算法 背包问题—
void Knapsack(int *v, int *w, int c, int n, int ** m) { int j; int jMax; if(w[n]-1>c) jMax=c; else jMax=w[n]-1; for (j = 0; j <= jMax ;j++) m[n][j] = 0; for (j = w[n]; j <= c; j++) m[n][j] = v[n] ; for ( int i=n-1; i>1; i--) { int jMax; if(w[n]-1>c) jMax=c; else jMax=w[n]-1; for (j = 0; j <= jMax; j++) m[i][j] = m[i+1][j]; for (j = w[i] ; j <= c; j++) if(m[i+1][j]> m[i+1][j-w[i]] + v[i] ) m[i][j]=m[i+1][j]; else m[i][j]=m[i+1][j-w[i]] + v[i] ; } m[1][c] =m[2][c]; if (c >= w[1]) m[1][c]=((m[1][c]>m[2][c-w[1]]+v[1])?m[1][c]:m[2][c-w[1]]+v[1]); }
0 0
w1=2 v1=6 w2=2 v2=3 w3=6 v3=5 w4=5 v4=4 w5=4 v5=6
1 0 0 0 0 0 0
2 0 6 6 6 6 6
3 0 6 6 6 6 6
4 0 6 9 9 9 9
5 0 6 9 9 9 9
6 0 6 9 9 9 12
7 0 6 9 9 10 12
8 0 6 9 11 11 15
2
解空间图示
以3个物品为例,解(0,1,0)表示(不取物品0,取物 root 品1,不取物品2)
0 1
0
1
0
1
0
1
0
3
0-1背包问题
问题陈述: 问题陈述: 给定n种物品和一背包。物品i的重量是wi 其价值为vi wi, vi, 给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的 容量为c。问应如何选择装入背包中的物品,使得装入背包中物品 容量为c 问应如何选择装入背包中的物品, 的总价值最大? 的总价值最大? 在选择装入背包的物品时,对每种物品i只有两种选择, 在选择装入背包的物品时,对每种物品i只有两种选择,即装入背 包或不装入背包。不能将物品i装入背包多次, 包或不装入背包。不能将物品i装入背包多次,也不能只装入部分 的物品i 因此,该问题称为0 背包问题。 的物品i。因此,该问题称为0-1背包问题。 解题思路: 解题思路: 此问题可转化为:给定c>0 wi>0,vi>0,1≤i≤n, c>0, 此问题可转化为:给定c>0,wi>0,vi>0,1≤i≤n,要求找出一 个n元0-1向量(x1,x2,…,xn),xi∈{0,1},1≤i≤n,使得 向量(x1,x2, xn),xi∈{0,1},1≤i≤n, (x1 wixi≤c,而且∑vixi达到最大 因此, 达到最大。 ∑wixi≤c,而且∑vixi达到最大。因此,0-1背包是一个特殊的 整数规划问题: 整数规划问题: max ∑vixi ∑wixi≤c, s.t. ∑wixi≤c, xi∈{0,1},1≤i≤n xi∈{0,1}, 可用动态规划算法求解。 可用动态规划算法求解。
13
一个例子
n=3,c=6,w={4,3,2},v={5,2,1}。
m(4,x) (0,0) m(4,x-2)+1 (2,1) m(3,x) (2,1) (0,0)
x
m(3,x) (2,1) (0,0) m(3,x-3)+2 (3,2)
x
m(2,x) (5,3) (0,0) (3,2) (2,1) (5,3)
8
1、0-1背包问题—动态规划算法举例 背包问题—
例如,有5个物品,其重量分别是{2, 2, 6, 5, 4},价值分别 为{6, 3, 5, 4, 6},背包的容量为10。 根据动态规划函数,用一个(n+1)×(C+1)的二维表V,V[i][j] 表示把前i个物品装入容量为j的背包中获得的最大价值。
x
x
m(2,x) (3,2) (2,1) (5,3)
x
m(2,x-4)+5 (7,7) (6,6) (4,5) (9,8) m(1,x)
x
(7,7) (6,6) (4,5) (3,2) (5,3) (0, 0) (2, 1) (9,8)
(0,0)
x
x
x
14
算法改进
• 函数 函数m(i,j)是由函数 是由函数m(i+1,j)与函数 与函数m(i+1,j-wi)+vi作max运 是由函数 与函数 作 运 算得到的。因此,函数m(i,j)的全部跳跃点包含于函数 的全部跳跃点包含于函数m(i+1, 算得到的。因此,函数 的全部跳跃点包含于函数 , j)的跳跃点集 的跳跃点集p[i+1]与函数 与函数m(i+1,j-wi)+vi的跳跃点集 的跳跃点集q[i+1]的 的跳跃点集 与函数 , 的跳跃点集 的 并集中。易知, 当且仅当wi≤ ≤ 且 并集中。易知,(s,t)∈q[i+1]当且仅当 ≤s≤c且(s-wi,t∈ 当且仅当 vi)∈p[i+1]。因此,容易由p[i+1]确定跳跃点集 ∈ 。因此,容易由 确定跳跃点集q[i+1]如下 如下 确定跳跃点集 q[i+1]=p[i+1]⊕(wi,vi)={(j+wi,m(i,j)+vi)|(j,m(i,j))∈p[i+1]} ⊕ ∈ • 另一方面,设(a,b)和(c,d)是p[i+1]∪q[i+1]中的 个跳跃 另一方面, 中的2个跳跃 , 和 , 是 ∪ 中的 则当c≥ 且 受控于(a, ,从而(c, 不是 点,则当 ≥a且d<b时,(c,d)受控于 ,b),从而 ,d)不是 时 , 受控于 p[i]中的跳跃点。除受控跳跃点外,p[i+1]∪q[i+1]中的其它跳 中的跳跃点。除受控跳跃点外, ∪ 中的其它跳 中的跳跃点 跃点均为p[i]中的跳跃点。 中的跳跃点。 跃点均为 中的跳跃点 • 由此可见,在递归地由表 由此可见,在递归地由表p[i+1]计算表 计算表p[i]时,可先由 计算表 时 可先由p[i+1] 计算出q[i+1],然后合并表 和表q[i+1],并清除其中的受 计算出 ,然后合并表p[i+1]和表 和表 , 控跳跃点得到表p[i]。 控跳跃点得到表 。
0 0
w1=2 v1=6 w2=2 v2=3 w3=6 v3=5 w4=5 v4=4 w5=4 v5=6
1
2
3
4
5
6
7
8
9
10
1 2 3 4 5
9
第一阶段,只装入前1个物品,确定在各种情况下的背包能够得到的最大价值; 第一阶段,只装入前 个物品,确定在各种情况下的背包能够得到的最大价值; 个物品 各种情况下的背包能够得到的最大价值 第二阶段,只装入前 个物品 确定在各种情况下的背包能够得到的最大价值; 个物品, 第二阶段,只装入前2个物品,确定在各种情况下的背包能够得到的最大价值; 依此类推,直到第 个阶段 最后, 个阶段。 便是在容量为C的背包中装入 依此类推,直到第n个阶段。最后,V(n,C)便是在容量为 的背包中装入 个物品 便是在容量为 的背包中装入n个物品 时取得的最大价值。 时取得的最大价值。
相关文档
最新文档