问题描述:
用多边形顶点的逆时针序列表示凸多边形,即
P={v
0
,v
1
,…,v
n-1
}
表示具有
n条边的凸多边形。
若
v
i
与
v
j
是多边形上不相邻的
2
个顶点,则线段
v
i
v
j
称为多边形的一条弦。弦将多边形分割成
2
个多边形
{v
i
,v
i+1
,…,v
j
}
和
{v
j
,v
j+1
,…v
i
}。
多边形的三角剖分
是将多边形分割成互不相交的三角形的弦的集合
T。
给定凸多边形
P
,以及定义在由多边形的边和弦组成的三角形上的权函数
w。要求确定该凸多边形的三角剖分,使得即该三角剖分中诸三角形上权之和为最小。
算法思路:
事实上,凸多边形的最优三角剖分问题有最优子结构性质,若凸(n+1)边形P={v
0
,v
1
,…,v
n
}
的最优三角剖分
T
包含三角形
v
0
v
k
v
n
,
1≤k≤n-1
,则
T
的权为
3
个部分权的和:三角形
v
0
v
k
v
n
的权,子多边形
{v
0
,v
1
,…,v
k
}
和
{v
k
,v
k+1
,…,v
n
}
的权之和。可以断言,由
T
所确定的这
2
个子多边形的三角剖分也是最优的。因为若有比
{v
0
,v
1
,…,v
k
}
或
{v
k
,v
k+1
,…,v
n
}
的更小权的三角剖分将导致
T不是最优三角剖分的矛盾。
•
定义
t[i][j]
,
1≤i<j≤n
为凸子多边形
{vi-1,vi,…,vj}
的最优三角剖分所对应的权函数值,即其最优值。为方便起见,设退化的多边形
{vi-1,vi}
具有权值
0
。据此定义,要计算的凸
(n+1)
边形
P
的最优权值为
t[1][n]。
•
t[i][j]
的值可以利用最优子结构性质递归地计算。当
j-i≥1
时,凸子多边形至少有
3
个顶点。由最优子结构性质,
t[i][j]
的值应为
t[i][k]
的值加上
t[k+1][j]
的值,再加上三角形
v
i-1
v
k
v
j
的权值,其中
i≤k≤j-1
。由于在计算时还不知道
k
的确切位置,而
k
的所有可能位置只有
j-i
个,因此可以在这
j-i
个位置中选出使
t[i][j]
值达到最小的位置。由此,
t[i][j]可递归地定义为:

实现代码:
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];
}