凸多边形最优三角剖分

合集下载

五大算法设计思想(转载)

五大算法设计思想(转载)

五⼤算法设计思想(转载)⼀分治法1.1 概念: 将⼀个难以直接解决的⼤问题,分割成⼀些规模较⼩的相同问题,以便各个击破,分⽽治之。

1.2 思想策略: 对于⼀个规模为n的问题,若该问题可以容易地解决(⽐如说规模n较⼩)则直接解决,否则将其分解为k个规模较⼩的⼦问题,这些⼦问题互相独⽴且与原问题形式相同,递归地解这些⼦问题,然后将各⼦问题的解合并得到原问题的解。

1.3 特征:1) 该问题的规模缩⼩到⼀定的程度就可以容易地解决2) 该问题可以分解为若⼲个规模较⼩的相同问题,即该问题具有最优⼦结构性质。

3) 利⽤该问题分解出的⼦问题的解可以合并为该问题的解;4) 该问题所分解出的各个⼦问题是相互独⽴的,即⼦问题之间不包含公共的⼦⼦问题。

1.4 对特征的解析:第⼀条特征是绝⼤多数问题都可以满⾜的,因为问题的计算复杂性⼀般是随着问题规模的增加⽽增加;第⼆条特征是应⽤分治法的前提它也是⼤多数问题可以满⾜的,此特征反映了递归思想的应⽤;第三条特征是关键,能否利⽤分治法完全取决于问题是否具有第三条特征,如果具备了第⼀条和第⼆条特征,⽽不具备第三条特征,则可以考虑⽤贪⼼法或动态规划法。

第四条特征涉及到分治法的效率,如果各⼦问题是不独⽴的则分治法要做许多不必要的⼯作,重复地解公共的⼦问题,此时虽然可⽤分治法,但⼀般⽤动态规划法较好。

1.5 基本步骤:1 分解:将原问题分解为若⼲个规模较⼩,相互独⽴,与原问题形式相同的⼦问题;2 解决:若⼦问题规模较⼩⽽容易被解决则直接解,否则递归地解各个⼦问题3 合并:将各个⼦问题的解合并为原问题的解。

1.6 适⽤分治法求解的经典问题:1)⼆分搜索2)⼤整数乘法3)Strassen矩阵乘法4)棋盘覆盖5)合并排序6)快速排序7)线性时间选择8)最接近点对问题9)循环赛⽇程表10)汉诺塔⼆动态规划2.1 概念 每次决策依赖于当前状态,⼜随即引起状态的转移。

⼀个决策序列就是在变化的状态中产⽣出来的,所以,这种多阶段最优化决策解决问题的过程就称为动态规划。

《算法设计与分析》第3章 动态规划法

《算法设计与分析》第3章 动态规划法

最优解的递推关系 定义m[i:j],表示矩阵连乘A[i:j]所需的最少计算 量 则有: i j 0 m[i ][ j ] i j minj{m[i ][ k ] m[k 1][ j ] pi 1 pk p j } i k
假设:N个矩阵的维数依序放在一维数组p中, 其中Ai的维数记为Pi-1×Pi
A=A1×A2×A3×…×An
A=(A1×A2×…×Ak) × (Ak+1×Ak+2×…×An)
B
C
1.2 穷举法
穷举法:列举出所有可能的计算次序,并计算出 每一种计算次序相应需要的数乘次数,从中找出 一种数乘次数最少的计算次序。
穷举法复杂度分析: 对于n个矩阵的连乘积,设其不同的计算次序有P(n)种。 由于每种加括号方式都可以分解为两个子连乘的加括号问题: (A1...Ak)(Ak+1…An)可以得到关于P(n)的递推式如下:
【程序】矩阵连乘的 穷举法实现 int MatrixChain::LookupChain(int i, int j) { if(i==j) return 0; int u=LookupChain(i+1,j)+p[i-1]*p[i]*p[j]; //k=i s[i][j]=i; //记录最优分解位置 for ( int k=i+1;k<j; k++ ) { //遍历k int t=LookupChain(i,k)+LookupChain(k+1,j) +p[i]*p[k+1]*p[j+1]; if (t<u) { u=t; s[i][j]=k; //记录最优分解位置 } } int MatrixChain::LookupChain() return u; { } return LookupChain(1,n);

《算法分析与设计》期末考试复习题纲(完整版)

《算法分析与设计》期末考试复习题纲(完整版)

《算法分析与设计》期末复习题一、选择题1.算法必须具备输入、输出和( D )等4个特性。

A.可行性和安全性 B.确定性和易读性C.有穷性和安全性 D.有穷性和确定性2.算法分析中,记号O表示( B ),记号Ω表示( A )A.渐进下界B.渐进上界C.非紧上界D.紧渐进界3.假设某算法在输入规模为n时的计算时间为T(n)=3*2^n。

在某台计算机上实现并完成概算法的时间为t秒。

现有另一台计算机,其运行速度为第一台的64倍,那么在这台新机器上用同一算法在t秒内能解输入规模为多大的问题( B )解题方法:3*2^n*64=3*2^xA.n+8 B.n+6C.n+7 D.n+54.设问题规模为N时,某递归算法的时间复杂度记为T(N),已知T(1)=1,T(N)=2T(N/2)+N/2,用O表示的时间复杂度为( C )。

A.O(logN) B.O(N)C.O(NlogN) D.O(N²logN)5.直接或间接调用自身的算法称为( B )。

A.贪心算法 B.递归算法C.迭代算法 D.回溯法6.Fibonacci数列中,第4个和第11个数分别是( D )。

A.5,89 B.3,89C.5,144 D.3,1447.在有8个顶点的凸多边形的三角剖分中,恰有( B )。

A.6条弦和7个三角形 B.5条弦和6个三角形C.6条弦和6个三角形 D.5条弦和5个三角形8.一个问题可用动态规划算法或贪心算法求解的关键特征是问题的( B )。

A.重叠子问题 B.最优子结构性质C.贪心选择性质 D.定义最优解9.下列哪个问题不用贪心法求解( C )。

A.哈夫曼编码问题 B.单源最短路径问题C.最大团问题 D.最小生成树问题10.下列算法中通常以自底向上的方式求解最优解的是( B )。

A.备忘录法 B.动态规划法C.贪心法 D.回溯法11.下列算法中不能解决0/1背包问题的是( A )。

A.贪心法 B.动态规划C.回溯法 D.分支限界法12.下列哪个问题可以用贪心算法求解( D )。

《算法分析与设计》期末测验复习题纲(完整版)

《算法分析与设计》期末测验复习题纲(完整版)

《算法分析与设计》期末测验复习题纲(完整版)————————————————————————————————作者:————————————————————————————————日期:《算法分析与设计》期末复习题一、选择题1.算法必须具备输入、输出和( D )等4个特性。

A.可行性和安全性 B.确定性和易读性C.有穷性和安全性 D.有穷性和确定性2.算法分析中,记号O表示( B ),记号Ω表示( A )A.渐进下界B.渐进上界C.非紧上界D.紧渐进界3.假设某算法在输入规模为n时的计算时间为T(n)=3*2^n。

在某台计算机上实现并完成概算法的时间为t秒。

现有另一台计算机,其运行速度为第一台的64倍,那么在这台新机器上用同一算法在t秒内能解输入规模为多大的问题?( B )解题方法:3*2^n*64=3*2^xA.n+8 B.n+6C.n+7 D.n+54.设问题规模为N时,某递归算法的时间复杂度记为T(N),已知T(1)=1,T(N)=2T(N/2)+N/2,用O表示的时间复杂度为( C )。

A.O(logN) B.O(N)C.O(NlogN) D.O(N²logN)5.直接或间接调用自身的算法称为( B )。

A.贪心算法 B.递归算法C.迭代算法 D.回溯法6.Fibonacci数列中,第4个和第11个数分别是( D )。

A.5,89 B.3,89C.5,144 D.3,1447.在有8个顶点的凸多边形的三角剖分中,恰有( B )。

A.6条弦和7个三角形 B.5条弦和6个三角形C.6条弦和6个三角形 D.5条弦和5个三角形8.一个问题可用动态规划算法或贪心算法求解的关键特征是问题的( B )。

A.重叠子问题 B.最优子结构性质C.贪心选择性质 D.定义最优解9.下列哪个问题不用贪心法求解( C )。

A.哈夫曼编码问题 B.单源最短路径问题C.最大团问题 D.最小生成树问题10.下列算法中通常以自底向上的方式求解最优解的是( B )。

凸三角形最优三角剖分

凸三角形最优三角剖分

凸三⾓形最优三⾓剖分问题相关定义:(1)凸多边形的三⾓剖分:将凸多边形分割成互不相交的三⾓形的弦的集合T。

(2)最优剖分:给定凸多边形P,以及定义在由多边形的边和弦组成的三⾓形上的权函数w。

要求确定该凸多边形的三⾓剖分,使得该三⾓剖分中诸三⾓形上权之和为最⼩。

下图为剖分案例。

若凸(n+1)边形P={V0,V1……Vn}的最优三⾓剖分T包含三⾓形V0VkVn,1<=k<=n,则T的权为三个部分权之和:三⾓形V0V k V n的权,多边形{V0,V1……V k}的权和多边形{V k,V k+1……V n}的权之和。

如下图所⽰:可以断⾔,由T确定的这两个⼦多边形的三⾓剖分也是最优的。

因为若有{V0,V1……V k}和{V0,V1……V k}更⼩权的三⾓剖分,将导致T不是最优三⾓剖分的⽭盾。

因此,凸多边形的三⾓剖分问题具有最优⼦结构性质。

3、递推关系:设t[i][j],1<=i<j<=n为凸多边形{V i-1,Vi……Vj}的最优三⾓剖分所对应的权值函数值,即其最优值。

最优剖分包含三⾓形Vi-1VkVj的权,⼦多边形{Vi-1,Vi……Vk}的权,⼦多边形{Vk,Vk+1……Vj}的权之和。

因此,可得递推关系式:凸(n+1)边形P的最优权值为t[1][n]。

三⾓剖分的结构及其相关问题。

凸三⾓形的三⾓剖分与表达式的完全加括号之间具有⼗分密切的关系。

正如所看到的⼀样,矩阵连乘的最优计算次序等价于矩阵链的最优完全加括号⽅式。

其实更加奇妙的地⽅是,这些问题似乎都是⼀个模⼦刻出来的!其实本质原因就是因为它们所对应的完全⼆叉树的同构性。

⼀个表达式的完全加括号⽅式相应于⼀棵完全⼆叉树,称为表达式的语法树。

⽽恰恰恰好的是,凸多边形的剖分也可以⽤语法数表⽰。

(请原谅“草滩⼩恪”画图功夫不⾏,⽆法画出对应的图) 模板主要代码://t[][] 记忆路径, s[][] 记录最优路径 W(,,)为权值函数const int maxn = 100;void minWeightTriangulation(int n, int t[][100], int s[][100]){for(int i=1; i<=n; i++) t[i][i] = 0;for(int r=2; r<=n; r++)for(int i=1; i<=n-r+1; i++){int j = i + r - 1;t[i][j] = t[i+1][j] + w(i-1, i, j);s[i][j] = i;for(int k = i+1; k<j; k++){int u = t[i][k] + t[k+1][j] + w(i-1, k, j);if(u<t[i][j]){t[i][j] = u;s[i][j] = k;}}}}代码如有疑问可参见“矩阵连乘”。

c++凸多边形的三角形剖分

c++凸多边形的三角形剖分

c++凸多边形的三角形剖分
C++中凸多边形的三角形剖分是一个常见的计算几何问题,可以通过多种方法来实现。

三角形剖分是将凸多边形分解为一系列不相交的三角形的过程,常用于图形渲染、碰撞检测和有限元分析等领域。

一种常见的方法是使用三角形扇剖分法,它从凸多边形的一个顶点开始,依次连接相邻顶点,将凸多边形分解为一系列三角形。

在C++中,可以通过遍历凸多边形的顶点,并使用C++中的数据结构(如数组、向量等)来存储和操作顶点信息,以及计算三角形的顶点索引,从而实现三角形扇剖分。

另一种常见的方法是使用Ear Clipping 算法,它通过逐步移除凸多边形的耳朵(一个顶点及其相邻的两条边),将凸多边形分解为一系列三角形。

在C++中,可以通过实现Ear Clipping算法的逻辑,遍历凸多边形的顶点,识别和移除耳朵,并构建三角形,来实现凸多边形的三角形剖分。

此外,还可以使用Delaunay 三角网格生成算法,它可以将凸多边形分解为一组无重叠的三角形,并且最小化了三角形的不良形
状。

在C++中,可以使用现有的Delaunay 三角网格生成算法的库来实现凸多边形的三角形剖分。

总之,在C++中实现凸多边形的三角形剖分,可以根据具体需求选择合适的方法,并结合C++的数据结构和算法来实现。

这些方法都需要考虑凸多边形的顶点顺序、边界情况以及三角形的顶点索引等细节,以确保准确和高效地进行三角形剖分。

凸多边形最优三角剖分

凸多边形最优三角剖分

凸多边形最优三⾓剖分相关概念凸多边形:当⼀个简单多边形及其内部构成⼀个闭凸集时,则称该简单多边形为⼀个凸多边形。

即凸多边形边界上或内部的任意两点所连成的直线段上所有点均在凸多边形的内部或边界上。

通常,⽤多边形顶点的逆时针序列表⽰凸多边形,即表⽰具有 n 条边,的凸多边形。

其中,约定。

弦:若与是多边形上不相邻的两个顶点,则线段称为多边形的⼀条弦。

弦将多边形分割成两个多边形和。

多边形的三⾓剖分三⾓剖分多边形的三⾓剖分是将多边形分割成互不相交的三⾓形的弦的集合 T。

下图为⼀个凸 7 边形的两个不同的三⾓剖分。

在凸多边形 P 的⼀个三⾓剖分 T 中,各弦互不相交,且集合T 已达到最⼤,即 P 的任⼀不在 T 中的弦必与 T 中某⼀弦相交。

在有 n 个顶点的凸多边形中,恰有 (n-3) 条弦和 (n-2) 个三⾓形。

最优三⾓剖分给定凸多边形,以及定义在由凸多边形的边和弦组成的三⾓形上的权函数 w ,要求确定该凸多边形的三⾓剖分,使得该三⾓剖分所应对的权,即三⾓剖分中诸三⾓形上权之和为最⼩。

最优⼦结构性质凸多边形的最优三⾓剖分问题有最优⼦结构性质。

事实上,若凸 (n+1) 边形,的最优三⾓剖分 T 包含三⾓形,则 T 的权为三⾓形的权,⼦多边形和的权之和。

可以断⾔,由 T 确定的这两个⼦多边形的三⾓剖分也是最优的。

因为若有和的更⼩权的三⾓剖分,将导致 T 不是最优三⾓剖分⽭盾。

最优三⾓剖分的递归结构令为凸⼦多边形的最优三⾓剖分对应的权函数值,即其最优值。

实现#include <bits/stdc++.h>using namespace std;const int N=7;int s[N][N],t[N][N],weight[][N]={{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}};int dp(int n);void Traceback(int i,int j);int Weight(int a,int b,int c);int main(){cout<<"此多边形的最优三⾓剖分值为:"<<dp(N-1)<<endl;cout<<"最优三⾓剖分结构为:"<<endl;Traceback(1,N-2);system("pause");return0;}int dp(int n){int i,r,j,k,u;for(i=1;i<=n;i++) t[i][i] = 0;for(r=2;r<=n;r++){for(i=1;i<=n-r+1;i++){j=i+r-1;t[i][j]=t[i+1][j]+Weight(i-1,i,j);s[i][j]=i;for(k=i+1;k<j;k++){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];}void Traceback(int i,int j){if(i==j) return;Traceback(i,s[i][j]);Traceback(s[i][j]+1,j);cout<<"三⾓剖分顶点:V"<<i-1<<",V"<<j<<",V"<<s[i][j]<<endl; }int Weight(int a,int b,int c){return weight[a][b]+weight[b][c]+weight[a][c];}。

算法设计与分析耿国华第三章

算法设计与分析耿国华第三章
算法
设计与分析
第三章 动态规划
主编 耿国华
Chapter
3
本章内容
3.1 动态规划基础
• 3.1.1 • 3.1.2 • 3.1.3 • 3.1.4
动态规划的基本思想
动态规划的基本要素 动态规划的基本步骤
动态规划示例——组合数问题
3.2 线性动态规划——合唱队形问题 3.3 区域动态规划——矩阵连乘问题
3.4 背包动态规划——0-1背包问题
3.5 树形动态规划——最优二叉搜索树问题 3.6 本章小结
Chapter
3
引言
本章给出的动态规划技术可使用较少的时间求解此类问题。
与分治法不同,在求解过程中动态规划方法采用自底向上的递 推方式,将原问题分解为互不独立的小规模子问题,根据子问
题的相关性从已知的各个局部解中选出能产生最佳解的部分,
• •
1. 问题描述 N位同学站成一排,音乐老师要请其中的(N-K)位同学 出列,而不改变其他同学的位臵,使得剩下的K位同学排
成合唱队形。
Chapter
3
3.2线性动态规划-----合唱队形问题 问题描述
• 1.问题描述

合唱队形要求:设K位同学从左到右依次编号为1,2,..., K,他们的身高分别为T1,T2,...,TK,则他们的身高满足 T1<...<Ti,且Ti >Ti+1>...>TK(1<=i<=K)。当给定队员人数N和 每个学生的身高T[i]时,计算需要多少学生出列,可以得到最长 的合唱队形。如下图所示:

i=1
i=2
步骤2:建立递归关系
i=3
j=1
j=2 j=3 j=4 j=5
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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 的欧氏距离。

相应于此权函数的最优三角剖分即为最小弦长三角剖分。

二、算法思路凸多边形的三角剖分与表达式的完全加括号方式之间具有十分紧密的联系。

正如所看到过的,矩阵连乘积的最优计算次序问题等价于矩阵链的完全加括号方式。

这些问题之间的相关性可从它们所对应的完全二叉树的同构性看出。

一个表达式的完全加括号方式对应于一棵完全二叉树,人们称这棵二叉树为表达式的语法树。

例如,与完全加括号的矩阵连乘积((A1(A2A3))(A4(A5A6)))相对应的语法树如图2(a)所示。

图2 表达式语法树与三角剖分的对应语法树中每一个叶子表示表达式中一个原子。

在语法树中,若一结点有一个表示表达式E1的左子树,以及一个表示表达式E r的右子树,则以该结点为根的子树表示表达式(E1E r)。

因此,有n个原子的完全加括号表达式对应于惟一的一棵有n个叶结点的语法树,反之亦然。

凸多边形{v0 ,v1 ,… ,v n-1}的三角剖分也可以用语法树来表示。

例如,图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}的三角剖分。

在一般情况下,一个凸n边形的三角剖分对应于一棵有n-1个叶子的语法树。

反之,也可根据一棵有n-1个叶子的语法树产生相应的一个凸n边形的三角剖分。

也就是说,凸n边形的三角剖分与n-1个叶子的语法树之间存在一一对应关系。

由于n个矩阵的完全加括号乘积与n个叶子的语法树之间存在一一对应关系,因此n个矩阵的完全加括号乘积也与凸(n+1)边形的三角剖分之间存在一一对应关系。

图2的(a)和(b)表示出了这种对应关系,这时n=6。

矩阵连乘积A1A2..A6中的每个矩阵A i对应于凸(n+1)边形中的一条边v i-1v i。

三角剖分中的一条弦v i v j,i<j,对应于矩阵连乘积A[i+1:j ]。

事实上,矩阵连乘积的最优计算次序问题是凸多边形最优三角剖分问题的一个特殊情形。

对于给定的矩阵链A1A2..A n,定义一个与之相应的凸(n+1)边形P={v0 ,v1 ,… ,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的最优三角剖分所对应的语法树给出矩阵链A1A2..A n的最优完全加括号方式。

三、实验源程序新建一个类CTriangle,Class type选择Generic Class。

Triangle.h代码typedef struct{int x;int y;}point;class CTriangle{public:bool Run();CTriangle();virtual ~CTriangle();private://用递归的方法输出剖分后的各个三角形void 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代码#define N 50#include <iostream.h>#include <math.h>#include <stdlib.h>#include "Triangle.h"CTriangle::CTriangle(){M = 0;t = new int *[N];s = new int *[N];for(int i=0 ; i<N ; i++){t[i] = new int[N];s[i] = new int[N];}v = new point[N];total = new int[N];}CTriangle::~CTriangle(){for(int i=0 ; i<N ; i++){delete []t[i];delete []s[i];}delete []t;delete []s;delete []v;delete []total;}int CTriangle::distance(point X, point Y) {int dis = (Y.x-X.x)*(Y.x-X.x) +(Y.y-X.y)*(Y.y-X.y);return (int)sqrt(dis);}int CTriangle::w(point X, point Y, point Z) {return distance(X,Y) + distance(Y,Z) + distance(Z,X); }bool CTriangle::Input(){int m;int a,b,c;cout<<"请输入凸多边形顶点个数:";cin>>m;M = m-1;for(int i=0 ; i<m ; i++){cout<<"输入顶点v"<<i<<"的坐标:"; cin>>v[i].x>>v[i].y;}//根据顶点坐标判断是否能构成一个凸多边形 for(int j=0 ; j<m ; j++){int p = 0;int q = 0;if(m-1 == j){a = v[m-1].y - v[0].y;b = v[m-1].x - v[0].y;c = b * v[m-1].y - a * v[m-1].x;}else{a = v[j].y - v[j+1].y;b = v[j].x - v[j+1].x;c = b * v[j].y - a * v[j].x;}for(int k=0 ; k<m ; k++){total[k] = a * v[k].x - b * v[k].y + c;if(total[k] > 0){p = p+1;}else if(total[k] < 0){q = q+1;}}if((p>0 && q>0) || (p==0 && q==0)){cout<<"无法构成凸多边形!"<<endl; exit(1);}}if(NULL != v) return true;elsereturn false;}bool CTriangle::minWeightTriangulation() {if(NULL == v)return false;for(int i=1 ; i<=M ; i++)t[i][i] = 0;for(int r=2 ; r<=M ; r++)for(int i=1 ; i<=M-r+1 ; i++){int j = i+r-1;t[i][j] = t[i+1][j] + w(v[i-1],v[i],v[j]); s[i][j] = i;for(int k=i+1 ; k<i+r-1 ; k++){int u = t[i][k] + t[k+1][j] +w(v[i-1],v[k],v[j]);if(u < t[i][j]){t[i][j] = u;s[i][j] = k;}}}return true;}void CTriangle::Traceback(int i, int j, int **s) {if(i == j)return;/*{cout<<"分成的三角形依次为:"<<endl; cout<<"v"<<i-1<<"v"<<i<<"v"<<j<<endl; }else*/Traceback(i,s[i][j],s);Traceback(s[i][j]+1,j,s);cout<<"三角形:v"<<i-1<<"v"<<s[i][j]<<"v"<<j<<endl;}bool CTriangle::Run(){if(Input()){ if(CTriangle::minWeightTriangulation()) {CTriangle::Traceback(1,M,s);cout<<endl;cout<<"最优权值之和为:"<<t[1][M]<<endl;return true;}elsereturn false;}elsereturn false;}main.cpp代码#include "Triangle.h"void main(){CTriangle triangle;triangle.Run();}四、测试结果给定的七个顶点坐标分别为(8,26)、(0,20)、(0,10)、(10,0)、(22,12)、(27,21)、(15,26),测试结果如下:该程序有一定的灵活性,用户可以自己选择顶点的个数以及顶点坐标,并对顶点坐标进行分析,判断这些顶点能否构成一个凸多边形,例如输入四个点坐标(0,0)、(0,10)、(4,4)、(10,0),这四个点构成的多边形显然是一个凹多边形,测试结果为:五、总结(1)凸多边形的最优三角剖分本来是一个几何问题,但通过分析,它本质上于矩阵连乘积的最优计算次序问题极为相似,从而可以将问题进行转化,用动态规划算法有效的解决这个问题。

相关文档
最新文档