凸多边形最优三角剖分
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
凸多边形最优三角剖分
一、问题描述
多边形是平面上一条分段线性的闭曲线。也就是说,多边形是由一系列首尾相接的直线段组成的。组成多边形的各直线段称为该多边形的边。多边形相接两条边的连接点称为多边形的顶点。若多边形的边之间除了连接顶点外没有别的公共点,则称该多边形为简单多边形。一个简单多边形将平面分为3个部分:被包围在多边形内的所有点构成了多边形的内部;多边形本身构成多边形的边界;而平面上其余的点构成了多边形的外部。当一个简单多边形及其内部构成一个闭凸集时,称该简单多边形为凸多边形。也就是说凸多边形边界上或内部的任意两点所连成的直线段上所有的点均在该凸多边形的内部或边界上。
通常,用多边形顶点的逆时针序列来表示一个凸多边形,即P={v0 ,v1,… ,v n-1}表示具有n条边v0v1,v1v2,… ,v n-1v n的一个凸多边形,其中,约定v0=v n。
若v i与v j是多边形上不相邻的两个顶点,则线段v i v j称为多边形的一条弦。弦将多边形分割成凸的两个子多边形{v i ,v i+1 ,… ,v j}和
{v j ,v j+1 ,… ,v i}。多边形的三角剖分是一个将多边形分割成互不相交的三角形的弦的集合T。图1是一个凸多边形的两个不同的三角剖分。
图1 一个凸多边形的2个不同的三角剖分
在凸多边形P的一个三角剖分T中,各弦互不相交,且弦数已达到最大,即P的任一不在T中的弦必与T中某一弦相交。在一个有n个顶点的凸多边形的三角剖分中,恰好有n-3条弦和n-2个三角形。
凸多边形最优三角剖分的问题是:给定一个凸多边形P={v0 ,v1 ,… ,v n-1}以及定义在由多边形的边和弦组成的三角形上的权函数ω。要求确定该凸多边形的一个三角剖分,使得该三角剖分对应的权即剖分中诸三角形上的权之和为最小。
可以定义三角形上各种各样的权函数ω。例如:定义ω(v i v j v k)=|v i v j|+|v i v k|+|v k v j|,其中,|v i v j|是点v i到v j的欧氏距离。相应于此权函数的最优三角剖分即为最小弦长三角剖分。
二、算法思路
凸多边形的三角剖分与表达式的完全加括号方式之间具有十分紧密的联系。正如所看到过的,矩阵连乘积的最优计算次序问题等价于矩阵链的完全加括号方式。这些问题之间的相关性可从它们所对应的完全二叉树的同构性看出。
一个表达式的完全加括号方式对应于一棵完全二叉树,人们称这棵二叉树为表达式的语法树。例如,与完全加括号的矩阵连乘积((A 1(A 2A 3))(A 4(A 5A 6)))相对应的语法树如图2(a)所示。
图2 表达式语法树与三角剖分的对应
语法树中每一个叶子表示表达式中一个原子。在语法树中,若一结点有一个表示表达式E 1的左子树,以及一个表示表达式E r 的右子树,则以该结点为根的子树表示表达式(E 1E r )。因此,有n 个原子的完全加括号表达式对应于惟一的一棵有n 个叶结点的语法树,反之亦然。
凸多边形{v 0 ,v 1 ,… ,v n-1}的三角剖分也可以用语法树来表示。例如,图1(a)中凸多边形的三角剖分可用图2(b)所示的语法树来表示。该语法树的根结点为边v 0v 6,三角剖分中的弦组成其余的内部结点。多边形中除v 0v 6边外的每一条边是语法树的一个叶结点。树根v 0v 6是三角形v 0v 3v 6的一条边,该三角形将原多边形分为3个部分:三角形v 0v 3v 6,凸多边形{v 0 ,v 1 ,… ,v 3}和凸多边形{v 3 ,v 4 ,… ,v 6}。三角形v 0v 3v 6的另外两条边,即弦v 3v 6和v 0v 3为根的两个儿子。以它们为根的子树分别表示凸多边形{v 0 ,v 1 ,… ,v 3}和凸多边形{v 3 ,v 4 ,… ,v 6}的三角剖分。
在一般情况下,一个凸n 边形的三角剖分对应于一棵有n-1个叶子的语法树。反之,也可根据一棵有n-1个叶子的语法树产生相应的一个凸n 边形的三角剖分。也就是说,凸n 边形的三角剖分与n-1个叶子的语法树之间存在一一对应关系。由于n 个矩阵的完全加括号乘积与n 个叶子的语法树之间存在一一对应关系,因此n 个矩阵的完全加括号乘积也与凸(n+1)边形的三角剖分之间存在一一对应关系。图2的(a)和(b)表示出了这种对应关系,这时n=6。矩阵连乘积A 1A 2..A 6中的每个矩阵A i 对应于凸(n+1)边形中的一条边v i-1v i 。三角剖分中的一条弦v i v j ,i 事实上,矩阵连乘积的最优计算次序问题是凸多边形最优三角剖分问题的一个特殊情形。 对于给定的矩阵链A 1A 2..A n ,定义一个与之相应的凸(n+1)边形P={v 0 ,v 1 ,… ,v n },使得矩阵A i 与凸多边形的边v i-1v i 一一对应。若矩阵A i 的维数为p i-1×p i ,i=1,2,…,n ,则定义三角形v i v j v k 上的权函数值为: ω(v i v j v k )=p i p j p k 。依此权函数的定义,凸多边形P 的最优三角剖分所对应的语法树给出矩阵链A 1A 2..A n 的最优完全加括号方式。 三、 实验源程序 新建一个类CTriangle ,Class ty pe 选择Generic Class 。 Triangle.h 代码 ty pedef struct { int x; int y; }point; class CTriangle { public: bool Run(); CTriangle(); v irtual ~CTriangle(); priv ate: //用递归的方法输出剖分后的各个三角形 v oid Traceback(int i,int j,int **s); //计算最优值算法 bool minWeightTriangulation(); //处理键盘输入,同时判断能否构成一个凸多边形 bool Input(); //计算三角形权值的函数 int w(point X,point Y,point Z); //计算平面上任意两点间距离的函数 int distance(point X,point Y); //记录最优三角剖分中所有三角形信息 int **s; //记录最优三角剖分所对应的权函数值 int **t; //记录凸多边形各顶点坐标 point *v; //记录坐标在直线方程中的值 int *total; int M; }; Triangle.cpp代码#def ine N 50 #include #include #include #include "Triangle.h" CTriangle::CTriangle() { M = 0; t = new int *[N]; s = new int *[N]; f or(int i=0 ; i t[i] = new int[N]; s[i] = new int[N]; } v = new point[N]; total = new int[N]; } CTriangle::~C Triangle() { f or(int i=0 ; i delete []t[i]; delete []s[i]; }