相关概念
凸多边形:当一个简单多边形及其内部构成一个闭凸集时,则称该简单多边形为一个凸多边形。即凸多边形边界上或内部的任意两点所连成的直线段上所有点均在凸多边形的内部或边界上。通常,用多边形顶点的逆时针序列表示凸多边形,即表示具有 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");
return 0;
}
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];}