原理
-
问题定义及目标
凸多边形最优三角剖分问题旨在给定一个凸多边形,通过添加若干条不相交的对角线将其分割成多个三角形,使得所有三角形的权值之和最小。这里的权值通常与三角形的顶点相关,可以是边长、角度或者其他自定义的度量值,在代码中通过权函数W(vi, vj, vk)
来计算以顶点vi
、vj
、vk
构成的三角形的权值。 -
动态规划思想及状态定义
- 状态定义:
使用二维数组m[i][j]
表示从顶点i
到顶点j
所构成的子多边形(包含这两个顶点以及它们之间按顺序的顶点)进行最优三角剖分后的最小权值和。例如,m[2][5]
表示由顶点2
、3
、4
、5
构成的子多边形的最优三角剖分的权值和。同时,使用二维数组s[i][j]
用于记录在m[i][j]
的最优剖分中,选择的划分顶点(即与i
和j
构成三角形的那个中间顶点),以便后续构造出具体的最优三角剖分方案。 - 状态转移方程及思想依据:
对于边界情况,当i = j
时,即子多边形只包含一个顶点,不存在三角剖分,所以m[i][i] = 0
。对于一般情况(i < j
),考虑从顶点i
到顶点j
的子多边形的最优三角剖分,其可以通过选择一个中间顶点k
(i < k < j
),将子多边形划分为两个子多边形(一个是从i
到k
,另一个是从k + 1
到j
),再加上以i
、k
、j
构成的三角形(其权值通过W(i - 1, k, j)
计算),然后取所有可能的中间顶点k
划分方式下的最小值作为m[i][j]
的值,状态转移方程可以表示为:
通过从较小规模的子多边形(即较小的j - i
值)逐步计算到整个多边形(i = 1
,j = n
),最终得到整个凸多边形的最优三角剖分的最小权值和存储在m[1][n]
中,同时s[1][n]
记录了对应的最优划分顶点信息。
- 状态定义:
步骤
-
初始化动态规划数组(外层第一个
for
循环部分)
通过循环for(int i = 1; i <= n; i++) m[i][i] = 0;
对m
数组进行初始化,将m
数组中对角线元素(即i = j
时)都设置为 0,因为单个顶点构成的子多边形不存在三角剖分,权值和自然为 0,这是边界情况的初始化。 -
动态规划计算最优三角剖分权值和及记录划分顶点(外层第二个
for
循环部分,包含多层嵌套循环)- 外层循环通过
for(r = 2; r <= n; r++)
控制子多边形的规模(这里用r
表示子多边形包含的顶点个数,从 2 个顶点开始逐步增加到整个多边形的n
&
- 外层循环通过