
1 最小代价多边形三角剖分算法
凸多边形的三角剖分是通过在非相邻顶点(角点)之间绘制对角线来形成的,这样对角线就不会相交。问题是如何以最小的代价找到三角剖分的代价。三角剖分的代价是其组成三角形的权重之和。每个三角形的重量是其周长(所有边的长度之和)
请参阅以下来源的示例。
多项式三角
同一凸五边形的两个三角剖分。左侧的三角测量的成本为8+2√2+2√5(约15.30),右侧的成本为4+2√2 + 4√5(约15.77)。
建议:在继续解决方案之前,请先在{IDE}上尝试您的方法。
 该问题具有递归子结构。其思想是将多边形分为三部分:单个三角形、左侧的子多边形和右侧的子多边形。我们尝试所有可能的分割,像这样,找到一个最小化三角形成本加上两个子多边形三角剖分成本的分割。
设顶点从i到j的三角剖分的最小代价为最小代价(i,j)
如果j<=i+2,则
最小成本(i,j)=0
其他的
最小成本(i,j)=最小{最小成本(i,k)+最小成本(k,j)+成本(i,k,j)}
这里k从“i+1”到“j-1”变化
由边(i,j)、(j,k)和(k,i)形成的三角形的成本为
成本(i,j,k)=距离(i,j)+距离(j,k)+距离(k,i)

2 源代码
using System;
using System.Collections;
using System.Collections.Generic;using Legalsoft.Truffer.TGraph;namespace Legalsoft.Truffer.Algorithm
{public static partial class Algorithm_Gallery{public static double MCPT_Solve(TPoint[] vertices, int i, int j){if (j < (i + 2)){return 0;}double cost = float.MaxValue;for (int k = i + 1; k <= j - 1; k++){double weight = vertices[i].Distance(vertices[j]) + vertices[j].Distance(vertices[k]) + vertices[k].Distance(vertices[i]);cost = Math.Min(cost, weight + MCPT_Solve(vertices, i, k) + MCPT_Solve(vertices, k, j));}return cost;}private static double MCPT_Cost(TPoint[] points, int i, int j, int k){TPoint p1 = points[i];TPoint p2 = points[j];TPoint p3 = points[k];return TPoint.Distance(p1, p2) + TPoint.Distance(p2, p3) + TPoint.Distance(p3, p1);}public static double MCPT_Solve(TPoint[] points, int n){if (n < 3){return 0;}double[,] table = new double[n, n];for (int gap = 0; gap < n; gap++){for (int i = 0, j = gap; j < n; i++, j++){if (j < i + 2){table[i, j] = 0.0;}else{table[i, j] = 1000000.0;for (int k = i + 1; k < j; k++){double val = table[i, k] + table[k, j] + MCPT_Cost(points, i, j, k);if (table[i, j] > val){table[i, j] = val;}}}}}return table[0, n - 1];}}
}

3 源程序
using System;
 using System.Collections;
 using System.Collections.Generic;
using Legalsoft.Truffer.TGraph;
namespace Legalsoft.Truffer.Algorithm
 {
     public static partial class Algorithm_Gallery
     {
         public static double MCPT_Solve(TPoint[] vertices, int i, int j)
         {
             if (j < (i + 2))
             {
                 return 0;
             }
double cost = float.MaxValue;
            for (int k = i + 1; k <= j - 1; k++)
             {
                 double weight = vertices[i].Distance(vertices[j]) + vertices[j].Distance(vertices[k]) + vertices[k].Distance(vertices[i]);
                cost = Math.Min(cost, weight + MCPT_Solve(vertices, i, k) + MCPT_Solve(vertices, k, j));
             }
            return cost;
         }
        private static double MCPT_Cost(TPoint[] points, int i, int j, int k)
         {
             TPoint p1 = points[i];
             TPoint p2 = points[j];
             TPoint p3 = points[k];
             return TPoint.Distance(p1, p2) + TPoint.Distance(p2, p3) + TPoint.Distance(p3, p1);
         }
        public static double MCPT_Solve(TPoint[] points, int n)
         {
             if (n < 3)
             {
                 return 0;
             }
             double[,] table = new double[n, n];
             for (int gap = 0; gap < n; gap++)
             {
                 for (int i = 0, j = gap; j < n; i++, j++)
                 {
                     if (j < i + 2)
                     {
                         table[i, j] = 0.0;
                     }
                     else
                     {
                         table[i, j] = 1000000.0;
                         for (int k = i + 1; k < j; k++)
                         {
                             double val = table[i, k] + table[k, j] + MCPT_Cost(points, i, j, k);
                             if (table[i, j] > val)
                             {
                                 table[i, j] = val;
                             }
                         }
                     }
                 }
             }
             return table[0, n - 1];
         }
     }
 }