- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1. 11.
}}}
8
算法设计与分析 >动态规划
3.10 0-1背包问题
有编号分别为a,b,c,d,e的五件宝石原石,它们的 重量分别是2,2,6,5,4千克,它们的价值分别是 6,3,5,4,6万元。 物品名称 重量(千克) 价值(万)
现在给你个承重为10千 克的背包,如何让背包 里装入的物品具有最大 的价值总和?
0 i j t[i][ j ] min{t[i][k ] t[k 1][ j ] w(vi 1vk v j )} i j i k j
7
算法设计与分析 >动态规划
4. 计算最优值
Void MinWeightTriangulation(int n, Type **t, int **s) 2. { for (int i = 1; i <= n; i++) t[i][i] = 0; 3. for (int r = 2; r <= n; r++) 4. for (int i = 1; i <= n – r +1; i++) { 5. int j = i + r – 1; 6. t[i][j] = t[i+1][j] + w(i–1, i, j); 7. s[i][j] = i; 8. for (int k = i + 1; k < j; k++) { 9. int u = t[i][k] + t[k+1][j] + w(i–1, k, j); 10. if (u < t[i][j]) {t[i][j] = u; s[i][j] = k;}
m(i, j) =
max{m(i+1, j), m(i+1, j–wi)+vi} j≥wi
显然,对于j为连续的,wi为实数时,m(i, j)依 然是梯状单调不减函数。
20
算法设计与分析 >动态规划
阶跃函数m(i, j)的跳跃点
• 实际上在m(i, j)的计算中并不需要将j逐渐加 1。因为m(i, j)有阶跃性。这样的点称为函数 m(i, j)的跳跃点,可以表示为(j, m(i,j))。
13
算法设计与分析 >动态规划
由0-1背包问题的最优子结构性质,可以建 立计算m( i , j )的递归式如下。 选择了物品i
的最优解
j wi m(i 1, j ), m(i 1, j wi ) vi } max{ m(i, j ) 0 j wi m(i 1, j )
•叶结点:矩阵
3
算法设计与分析 >动态规划
2、最优子结构性质
最优三角剖分问题
输入:多边形P 和代价函数W 输出:求P 的三角剖分T,使得ห้องสมุดไป่ตู้价 Σs∈STW(s)最小,其中ST 是T 所对应 的三角形集合
4
算法设计与分析 >动态规划
3、最优三角剖分的递归结构
定义t[i][j],1≤i<j≤n为凸子多边形{vi-1,vi,…,vj}
1. jMax=min(w[i]-1,c); 如果第i个物品不能放入背包,则m(i,j)=m(i+1,j) int 2. (int 否则,比较放与不放两种情况下哪种更优,取更优的值 for j = 0; j <= jMax; j++) 最为 的值。 m[i][ j m(i,j) ] =m[i+1][j]; (int j = w[i]; j <= c; j++) 3. for 考虑第一个物品,不能放的话 m(1,c)=m(2,c);否 m[i][j] = max(m[i+1][j], m[i+1][j-w[i]] + v[i]); } 则 m(1,c)= 放的情况下和不放情况下的最大值。 m[1][c] =m[2][c]; 4. 返回m(1,c) if (c >= w[1]) m[1][c] = max(m[1][c], m[2][c-w[1]] + v[1]); 16 }
j wn vn m(n, j ) 0 0 j wn
max(i,j)
4,6
当i=5时,
j4 6 m(5, j ) 0 0 j 4
j
该函数是关于变量j的阶梯状函数。
19
算法设计与分析 >动态规划
• 对于每一个确定的i,函数m(i, j)是关于变量j的阶 梯状单调不减函数: • 由0-1背包问题的递归式 m(i+1, j) 0≤j<wi 可知每当j增大超过一个物品的重量wi时,函数 m(i, j)便有可能增加vi,因而形成了关于变量j的 阶梯状单调不减函数。
11
算法设计与分析 >动态规划
如果不是最优 解,进行替代, 矛盾!
12
算法设计与分析 >动态规划
设所给0-1背包问题的子问题: 最优值m(i , j)是
max v k x k
k i n
n wk x k j k i x k {0,1}, i k n
即m(i ,j)是背包容量为 j,可选择物品为 i, i+1,…,n时0-1背包问题的最优值。
2. 从第n-1行开始到第2行,一行一行的填写m。假设 i行 for 当前填写的是第 (int i = n - 1; i > 1; i-) { // 计算剩下的m
算法设计与分析 >动态规划
void Traceback(T **m, int w[ ], int c, int n, int x[]) { // 计算x[i],它表示i物品是否装入背包 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; }
a b c d e
2 2 6 5 4
6 3 5 4 6
9
算法设计与分析 >动态规划
给定n种物品和一背包。物品i的重量是 wi,其价值为vi,背包的容量为C。问应如何 选择装入背包的物品,使得装入背包中物品 的总价值最大? 对每种物品i只有两种选择,即装入背包 或者不装入背包,不能将物品i重复装入,也 不允许部分装入,因此,该问题被称为0-1背 包问题。
(d, e)实际上受控于 (a, b),被称为受控跳跃点。 m(i, j)
因此,将前面产生的跳跃点中的受控跳跃点删除, b 便可得到P[i]中的跳跃点。 e 由此便可得到计算表P[i]的算法。
10
算法设计与分析 >动态规划
0-1背包问题是一个特殊的整数规划问题。问 题的解是找出一个n元的0,1向量{x1, x2,……xn}, 使得
n wi xi C i 1 xi {0,1},1 i n
max vi xi
i 1
n
xi表示物品i是 否装入背包
15
算法设计与分析 >动态规划
void Knapsack(Type v[], int w[], int c, int n, Type **m) { 算法说明 : int 处理最简单情况,即填好 jMax=min(w[n]-1,c); 1. m(n,j)。当j<wn时, for (int j = 0; j <= jMax; j++) m[n][j] = 0; // 初始化m [n][] m(n,j)=0; 当j<wn时, m(n,j)=v[n]; for (int j = w[n]; j <= c; j++) m[n][ j ] = v[n];
22
算法设计与分析 >动态规划
跳跃点的递推关系
函数m(i,j)=
max{m(i+1, j), m(i+1, j–wi)+vi} 函数m(i,j)的全部跳跃点
p[i+1]=m(i+1,j)的跳跃点集
q[i+1]=m(i+1, j–wi)+vi的跳 跃点集 23
算法设计与分析 >动态规划
例子:n=5,c=10,w={2,2,6,5,4},v={6,3, 5,4,6},计算p[i] i=6 p[6]={(0,0)} i=5 p[5]={(0,0), (4,6)} q[6]=p[6](w5,v5)={(4,6)} q[5]={(5,4),(9,10)}
17
算法设计与分析 >动态规划
算法复杂度分析: 从m(i,j)的递归式容易看出,算法需要O(nc) 计算时间。
存在的不足: 求物品重量wi是整数 当背包容量c很大时,算法需要的计算时 间较多。例如,当c>2n时,算法需要Ω(n2n) 计算时间。
18
算法设计与分析 >动态规划
背包容量为实数时, 递归公式仍然成立 例子:n=5,c=10,w={2,2,6,5,4},v={6,3, 5,4,6}由计算m(i,j)的递归式,
m(i, j) xi,m(i, xi)
0
xi
c
j
21
算法设计与分析 >动态规划
跳跃点决定了函数m(i, j)
• 显然在m(i, j)的计算中,只需要计算它的跳 跃点。 • 在变量j是连续的情况下,我们可以对每个 确定的i (1≤i≤n),用一个表P[i]来保存m(i, j) 的全部跳跃点。 • 对于每一个确定的实数j,可以通过查表P[i] 来确定m(i, j)的值。 • 由于m(i, j)是单调不减的阶梯函数,所以P[i] 中的全部跳跃点的值也是递增排列的。