赞
踩
三角剖分(Triangulation)也叫做三角化,或者分格化,就是对给定的平面点集,生成三角形集合的过程,即将复杂的多边形剖分成多个三角。
考虑平面点集P={ P1...Pn },我们希望得到三角形集合T=在{ t1...tm },满足:
a)所有三角形的端点恰好构成集合P。
b)任意两个三角形的边不相交(要么重合,要么没有交点)。
c)所有三角形的合集构成P的凸包。
使用动态规划算法解凸多边形最优三角剖分问题,具体来说就是,依据递归式,按照顺序求得子问题,使得该三角剖分中诸三角形上权之和为最小。
[输入:] 在屏幕上输入凸多边形顶点个数和顶点坐标。按逆时针顺序输入顶点坐标。
[输出:] 最优三角剖分后的三角形顶点。
凸多边形的最优三角剖分问题有最优子结构性质
若凸(n+1)边形P=<v0 ,v1 ,… ,vn>的一个最优三角剖分T包含三角形v0 vk vn ,1≤k≤n-1,则T的权为3个部分权的和,即三角形v0 vk vn的权,子多边形<v0 ,v1 ,… ,vk>的权和<vk ,vk+1 ,… ,vn>的权之和。由T所确定的这两个子多边形的三角剖分也是最优的,因为若有<v0 ,v1 ,… ,vk>或<vk ,vk+1 ,… ,vn>的更小权的三角剖分,将会导致T不是最优三角剖分的矛盾。
定义t[i,j],1≤i<j≤n,为凸子多边形<vi-1 ,vi ,… ,vj>的最优三角剖分所对应的权值,即最优值。
设退化的多边形<Vi-1 ,vi>权值为0,那么凸(n+1)边形对应的权的最优值为t[1,n]。
t[i,j]的值可以利用最优子结构性质递归地计算。由于退化的2顶点多边形的权值为0,所以t[i,i]=0,i=1,2,…,n 。当j-i≥1时,子多边形<vi-1 ,vi ,… ,vj>至少有3个顶点。
由最优子结构性质,t[i,j]的值应为t[i,k]的值加上t[k+1,j]的值,再加上vi-1 vk vj的权值,并在i≤k≤j-1的范围内取最小。由此,t[i,j]可递归地定义为:
计算凸(n+1)边形P=<v0 ,v1 ,… ,vn>的三角剖分最优权值的动态规划算法,输入是凸多边形P=<v0 ,v1 ,… ,vn>的权函数ω,输出是最优值t[i,j]和使得t[i,k]+t[k+1,j]+ω(△vi-1vkvj)达到最优的位置(k=)s[i,j],1≤i≤j≤n 。
对于任意的1≤i≤j≤n ,上述算法在计算每一个子多边形<vi-1 ,vi ,… ,vj>的最优三角剖分所对应的权值t[i,j]的同时,还在s[i,j]中记录了此最优三角剖分中与边(或弦)vi-1vj构成的三角形的第三个顶点的位置。
因此,利用最优子结构性质并借助于s[i,j],1≤i≤j≤n ,凸(n+l)边形P=<v0 ,v1 ,… ,vn>的最优三角剖分可容易地在Ο(n)时间内构造出来
- #include<bits/stdc++.h>
- using namespace std;
-
- const int N = 7; //凸多边形边数+1
- int 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 MinWeightTriangulation(int n, int **t, int **s);//此多边形的最优三角剖分值
- void Traceback(int i, int j, int **s); //构造最优解
- int Weight(int a, int b, int c); //权函数
-
- int main()
- {
- int **s = new int *[N];
- int **t = new int *[N];
- for(int i=0; i<N; i++)
- {
- s[i] = new int[N];
- t[i] = new int[N];
- }
- cout<<"此多边形的最有三角剖分值为:"<<MinWeightTriangulation(N-1, t, s)<<endl;
- cout<<"最优三角剖分结构为:"<<endl;
- Traceback(1, 5, s); //s[i][j]记录了Vi-1和Vj构成三角形的第三个顶点的位置
- system("pause");
- return 0;
- }
- 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)
- {
- int j = i+r-1;
- t[i][j] = t[i+1][j] + Weight(i-1, i, j);
- s[i][j] = i;
- for(int k=i+1; k<i+r-1; k++)
- {
- 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];
- }
- void Traceback(int i, int j, int **s)
- {
- if(i==j) return;
- Traceback(i, s[i][j], s);
- Traceback(s[i][j]+1, j, s);
- 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];
- }
运行截图:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。