问题相关定义:
(1)凸多边形的三角剖分:将凸多边形分割成互不相交的三角形的弦的集合T。
(2)最优剖分:给定凸多边形P,以及定义在由多边形的边和弦组成的三角形上的权函数w。要求确定该凸多边形的三角剖分,使得该三角剖分中诸三角形上权之和为最小。
凸多边形三角剖分如下图所示:
相关性质
在凸多边形P的一个三角形部分T中,各弦互不相交,且弦数已达到最大,即P的任一不在T中的弦必与T中某一弦相交。在一个有n个顶点的凸多边形的三角部分中,恰好有n-3条弦和n-2个三角形。
最优子结构性质
若凸(n+1)边形
P=V0,V1……Vn
的最优三角剖分T包含三角形
V0VkVn
,1<=k<=n,则T的权为三个部分权之和:三角形
V0VkVn
的权,多边形
V0,V1……Vk
的权和多边形
Vk,Vk+1……Vn
的权之和。如下图所示:
可以断言,由T确定的这两个子多边形的三角剖分也是最优的。因为若有
V0,V1……Vk
和
Vk,Vk+1……Vn
的更小权的三角剖分,将导致T不是最优三角剖分的矛盾。因此,凸多边形的三角剖分问题具有最优子结构性质。
子问题重叠性质
子问题重叠性质是指在用递归算法自顶向下对问题进行求解时,每次产生的子问题并不总是新问题,有些子问题会被重复计算多次。
动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题时,只是在表格中简单地查看一下结果,从而获得较高的解题效率。
显然凸多边形的最优三角划分具有子问题重叠性质。例如下面的示例:
在求解该六边形的最优三角划分时,会包含子问题
<V0,V1,V2,V3>
<script type="math/tex" id="MathJax-Element-599">
</script>和子问题
<V1,V2,V3,V4>
<script type="math/tex" id="MathJax-Element-600">
</script>,这两个子问题豆包含同一个子问题
<V1,V2,V3>
<script type="math/tex" id="MathJax-Element-601">
</script>的最优三角划分,都需要计算多边形
<V1,V2,V3>
<script type="math/tex" id="MathJax-Element-602">
</script>的权。
递推关系辅
设t[i][j],1<=i < j<=n 为凸多边形{Vi-1,Vi……Vj}的最优三角剖分所对应的权值函数值,即其最优值。最优剖分包含三角形Vi-1VkVj的权,子多边形{Vi-1,Vi……Vk}的权,子多边形{Vk,Vk+1……Vj}的权之和。
因此,可得递推关系式:
凸(n+1)边形P的最优权值为t[1][n]。
程序清单
Int MinWeightTriangulation(int n,int **t,int **s)
{
for(int i=1; i<=n; i++) {
t[i][i] = 0; }
for(int r=2; r<=n; r++) //r为当前计算的链长(子问题规模)
{
for(int i=1; i<=n-r+1; i++)//n-r+1为最后一个r链的前边界
{
int j = i+r-1;//计算前边界为r,链长为r的链的后边界
t[i][j] = t[i+1][j] + Weight(i-1,i,j);//将链ij划分为A(i) * ( A[i+1:j] )这里实际上就是k=i
s[i][j] = i;
for(int k=i+1; k<j; k++) {
//将链ij划分为( A[i:k] )* (A[k+1:j])
int u = t[i][k] + t[k+1][j] + Weight(i-1,k,j);
if(u<t[i][j])
{
t[i][j] = u;
s[i][j] = k;
}
}
}
}
return t[1][N-2]; //(N为凸多边形的边数加1)
}
//时间复杂度为O(n3)
凸多边形的最优三角划分和矩阵链乘法的同构
凸多边形的三角剖分与矩阵链乘法完全加括号方式之间具有十分紧密的联系。正如所看到过的,矩阵连乘积的最优计算次序问题等价于矩阵链的完全加括号方式。这些问题之间的相关性可从它们所对应的完全二叉树的同构性看出。
一个表达式的完全加括号方式对应于一棵完全二叉树,人们称这棵二叉树为表达式的语法树。例如,与完全加括号的矩阵链乘积((A1(A2A3))(A4(A5A6)))相对应的语法树如图2(a)所示。
表达式语法树与三角剖分的对应
图1(a)中凸多边形的三角剖分可用图2(b)所示的语法树来表示。该语法树的根结点为边v0v6,三角剖分中的弦组成其余的内部结点。多边形中除v0v6边外的每一条边是语法树的一个叶结点。树根v0v6是三角形v0v3v6的一条边,该三角形将原多边形分为3个部分:三角形v0v3v6,凸多边形{v0 ,v1 ,… ,v3}和凸多边形{v3 ,v4 ,… ,v6}。三角形v0v3v6的另外两条边,即弦v3v6和v0v3为根的两个儿子。以它们为根的子树分别表示凸多边形{v0 ,v1 ,… ,v3}和凸多边形{v3 ,v4 ,… ,v6}的三角剖分。
举个栗子
Example:{V0,V1,V2,V3,V4,V5}={{0,2,2,3,1,4},{2,0,1,5,2,3},{2,1,0,2,1,4},{3,5,2,0,6,2},{1,2,1,6,0,1},{4,3,4,2,1,0}}//凸多边形的权值
A:i=j(i=1;i<=n;i++) t[i][j]=0;
B:k=i(i=1;i<=n;i++)
(a)r=2 时j=i=r-1
t[1][2]=t[1][1]+t[2][2]+w(0,1,2)=0+0+5=5
t[2][3]=t[2][2]+t[3][3]+w(1,2,3)=8
t[3][4]=t[3][3]+t[4][4]+w(2,3 ,4)=9
t[4][5]=t[4][4]+t[5][5]+w(3,4,5)=9
(b)r=3时j=i+r-1
t[1][3]=t[1][1]+t[2][3]+w(0,1,3)=18
t[2][4]=t[2][2]+t[3][4]+w(1,2,4)=13 (v2v3v4和v1v2v4)
t[3][5]=t[3][3]+t[4][5]+w(2,3,5)=17
(c)r=4时j=i+r-1
t[1][4]=t[1][1]+t[2][4]+w(0,1,4)=18 (v0v1v4和v2v3v4和v1v2v4)
t[2][5]=t[2][2]+t[3][5]+w(1,2,5)=25 (v2v3v4和v2v4v5和v1v2v5)
C:k=i+1
r=3
t[1][3]=t[1][2]+t[3][3]+w(0,2,3)=12 (v0v1v2和v0v2v3)
t[2][4]=t[2][3]+t[4][4]+w(1,3,4)=21
t[3][5]=t[3][4]+t[5][5]+w(2,4,5)=15 (v2v3v4和v2v4v5)
r=4
t[1][4]=t[1][2]+t[3][4]+w(0,2,4)=19
t[2][5]=t[2][3]+t[4][5]+w(1,3,5)=27
当k=i时
t[1][5]=t[1][1]+t[2][5]+w(0,1,5)=34
当k=i+1时
t[1][5]=t[1][2]+t[3][5+w(0,2,5)=30
t[1][5]=t[1][3]+t[4][5]+w(0,3,5)=30
t[1][5]=t[1][4]+t[5][5]+w(0,4,5)=18+6=24 (v0v1v4和v2v3v4和v1v2v4和v0v4v5)
一个栗子当然不过瘾
4.Suppose a convex polygon has six edges, vertex coordinates
V0,V1,V2,...V5
is (0,0),(5,0),(8,1),(9,2),(9,4),(8,6). The weight function w is the Euclidean distance, determines the optimal triangulation of the convex polygon. Requirements: The results should contain pseudo-code, the optimal triangulation, Apply the matrix algorithm to write the matrix of this problem.
Solution: