120 likes | 257 Views
算法设计与分析 第三章 动态规划. 杨圣洪. 分治法的基本思想. 分治法的基本思想 将一个规模为 n 的问题分解为 k 个 规模较小的子问题,这些子问题互相 独立 且与 原问题 相同。 对这 k 个子问题分别求解。如果子问题的规模仍然不够小,则再划分 为 k 个子 问题,如此递归的进行下去,直到问题规模足够小,很容易求出其解为止。 将求出的小规模的问题的解 合并 为一个更大规模的问题的解, 自底向上 逐步求出原来问题的解。 将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。. 动态规划 基本步骤.
E N D
算法设计与分析第三章 动态规划 杨圣洪
分治法的基本思想 • 分治法的基本思想 • 将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同。 • 对这k个子问题分别求解。如果子问题的规模仍然不够小,则再划分为k个子问题,如此递归的进行下去,直到问题规模足够小,很容易求出其解为止。 • 将求出的小规模的问题的解合并为一个更大规模的问题的解,自底向上逐步求出原来问题的解。 • 将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
动态规划基本步骤 • 找出最优解的性质,并刻划其结构特征。判断整体最优是否有局部最优 • 递归定义最优值。有难度。 • 以自底向上的方式计算出最优值。非递归 • 根据计算最优值时得到的信息,构造最优解。!
3.5 凸多边形最优三角剖分 • 用多边形顶点的逆时针序列表示凸多边形,即P={v0,v1,…,vn-1}表示凸多边形。如:{V0,V6,V5,V4,V3,V2,V1} • 若vi与vj不相邻则线段vivj称为多边形的一条弦,如(V1,V3)。弦将多边形分割成2个多边形{vi,vi+1,…,vj}和{vj,vj+1,…vi}。如{v1,v2,v3},{v3,v4,…,v1} • 三角剖分=互不相交的三角形的 集合T。 • 给定凸多边形P以及定义在三角形上的权函数w。寻找三角形上权之和为最小的三角剖分。 • 弦不同则划分不同,即不同点间连线不同则划分不同 • 下图为二个不同的剖分。
三角剖分的结构及其相关问题 • 一个表达式的完全加括号方式可用完全二叉树描述,表达式的语法树。 • 例如,((A1(A2A3))(A4(A5A6)))运算次序所相应的语法树如图 (a)所示。 • 凸多边形{v0,v1,…vn-1}的三角剖分也可以用语法树表示 • 例如,图 (b)中凸多边形的三角剖分可用图 (a)所示的 语法树 表示。 • 矩阵连乘积中的每个矩阵Ai凸(n+1)边形中的一条边vi-1vi。 • 三角剖分中的一条弦vivj,i<j矩阵连乘积A[i+1:j]。
最优子结构性质 • 凸多边形最优三角剖分问题是最优子结构。(以下板) • 若凸(n+1)边形P={v0,v1,…,vn-1 ,vn}的最优三角剖分T包含三角形v0vkvn,如v0v3v6 • T分为:v0vkvn,子多边形{v0, v1, …,vk}和{vk,vk+1,…,vn}。如{v0v1v2v3}, {v3v4v5v6} • 这2个子多边形的三角剖分也是最优的。 • 若{v0,v1,…,vk}或{vk,vk+1,…,vn}不是最优,即还有更小权的三角剖分,将导致T不是最优三角剖分的矛盾。
最优三角剖分的递归结构 • 用t[i][j](1≤i<j≤n)表凸子多边形{vi-1,vi,…,vj}的最优三角剖分权函数值,约定t[i][i]= 0即退化多边形{vi-1,vi}权值为0 • t[1][n]为凸(n+1)边形P的最优权值,各三角形的边长和。 • 利用最优子结构递归地计算t[i][j]。 • 当j-i1时,凸子多边形至少有3个顶点(i-1,i,j)。 • t[i][j]=子多边t[i][k]+子多边t[k+1][j]+三角形vi-1vkvj • i≤k≤j-1,k有j-i个值,在其中选出使t[i][j]达到最小的k
算法描述 m[i,j]=min(m[i,k]+m[k+1,j]+pi-1pkpj), • 矩阵连乘的算法 void MatrixChain(int *p,int n,int **m,int **s){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++) {m[i][j] = 0; }} for (int r = 2; r <= n; r++) //两两相乘到n个相乘 for (int i = 1; i <= n - r+1; i++) { //起点i int j=i+r-1; //终点j //m[i][j]=m[i][i]+m[i+1][j]+p[i-1]*p[i]*p[j];s[i][j]=i;//初值 for (int k =i; k < j; k++) { //断点k=i+1~j-1 int t = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j]; if (t < m[i][j]) { m[i][j] = t; s[i][j] = k;} } } }
计算最优值 t[i,j]=min(t[i,k]+t[k+1,j]+w(vi-1vkvj), • void MinWT(int n, type **t, int **s) { //此处n=点数-1,因为v0,v1,…,vn for (int i=1;i<=n;i++) t[i][i]=0; //对应m[i][i]=0 for (int r=2; r<=n; r++) //区间长度 for (i=1; i<=n-r+1; i++){ //区间起点i int j=i+r-1; //区间终点j t[i][j]=t[i][i]+t[i+1][j]+dw(i-1,i,j);//k=i s[i][j]=i; for (int k=i+1;k<j;k++){ int u=t[i][k]+t[k+1][j]+dw(i-1,k,j);//t[i-1][k]+t[i-1][j]+w[i-1][k][j] if (u<t[i][j]){t[i][j]=u;s[i][j]=k;} } } } • 复杂性:T(n)=O(n3) S(n)=O(n2) dw(i,j,k)=w[i,j]+w[j,k]+w[i,k] 距离阵 • 采用矩阵次序中方法获取其构造过程 代码见mwt.htm
最优三角形划分 S[1][4]=3则(0,4,3)构成三角形 S[1][3]=2则(0,3,2)构成三角形 中间弦重复加了180 ---------------- S[2][4]=2则(1,4,2)构成三角形 S[1][2]=1则(0,2,1)构成三角形 S[2][3]=2则(1,3,2)构成三角形 S[3][4]=3则(2,4,3)构成三形形
构造最优解 • 思考:构造一个在O(n)时间内的求最优解的算法? • 仍采用矩阵次序中的方法或函数 • traceBack(1,n); • traceBack2(n);