假设顶点的总数为n,从0到n-1. 从序号为0的顶点开始以逆时针方向排序,对于
令子问题A[i,j]为包含顶点i,i+1, . . . j的凸多边形的最小三角剖分代价,dist(i,j)为顶点i到顶点j的距离。对于子问题A[i,j],考虑边e(i,j)最终会在某个三角形内,为了找出这个三角形,计算i到j之间的每个顶点k与i和j围成的三角形的对角线的和的最小值即为A[i,j],找出对角线和的最小值所对应的k,再继续查找A[i,k],A[k,j],直到多边形不能再划分为止,因此的到递推式
1 package org.xiu68.ch06.ex6; 2 3 public class Ex6_12 { 4 5 public static Point[] ps1,ps2; 6 //凸多边形的最优三角形剖分,求所有对角线之和的最小值 7 public static void main(String[] args) { 8 // TODO Auto-generated method stub 9 /* 10 最小三角剖分代价为:8.47213595499958 11 三角形划分方式为: 12 Point:0,Point:4,Point:1 13 Point:1,Point:4,Point:2 14 */ 15 ps1=new Point[]{ 16 new Point(2,0), 17 new Point(0,2), 18 new Point(0,4), 19 new Point(4,4), 20 new Point(4,2) 21 }; 22 int[][] arr1=new int[ps1.length][ps1.length]; 23 minTriangle(ps1,arr1); //8.47213595499958 24 System.out.println("三角形划分方式为:"); 25 divide(arr1,0,ps1.length-1); 26 27 /* 28 最小三角剖分代价为:11.21110255092798 29 三角形划分方式为: 30 Point:0,Point:5,Point:1 31 Point:1,Point:5,Point:3 32 */ 33 System.out.println(); 34 ps2=new Point[]{ 35 new Point(0,2), 36 new Point(10,4), 37 new Point(12,4), 38 new Point(13,2), 39 new Point(12,0), 40 new Point(10,0) 41 }; 42 int[][] arr2=new int[ps2.length][ps2.length]; 43 minTriangle(ps2,arr2); //11.21110255092798 44 System.out.println("三角形划分方式为:"); 45 divide(arr2,0,ps2.length-1); 46 } 47 48 //B中存放三角形的第三个顶点 49 public static void minTriangle(Point[] ps,int[][] B){ 50 double[][] A=new double[ps.length][ps.length]; //子问题A[i][j]的最优三角剖分代价 51 52 for(int i=0;i<A.length;i++) 53 for(int j=0;j<A[i].length;j++){ 54 A[i][j]=0; 55 B[i][j]=0; 56 } 57 58 for(int s=4;s<=ps.length;s++){ //包含s个顶点的多边形的最优剖分代价 59 for(int i=0;i<ps.length-s+1;i++){ //包含s个顶点的多边形的开始顶点,以逆时针方向前进 60 int j=i+s-1; //包含s个顶点的多边形的结束顶点 61 A[i][j]=Double.MAX_VALUE; 62 double temp=A[i][j]; 63 64 //t为i和j的相对顶点,从i的后一个顶点开始,结束顶点为j的前一个顶点 65 for(int t=i+1;t<=j-1;t++){ 66 if(t==i+1){ //t为i的后一个顶点 67 temp=dist(ps,t,j)+A[t][j]; 68 } 69 else if(t==j-1){ //t为j的前一个顶点 70 temp=dist(ps,i,t)+A[i][t]; 71 }else{ //t处于i的后一个顶点之后,j的前一个顶点之前 72 temp=dist(ps,i,t)+dist(ps,j,t)+A[i][t]+A[t][j]; 73 } 74 if(A[i][j]>temp){ 75 A[i][j]=temp; 76 B[i][j]=t; 77 } 78 }//3 79 }//2 80 }//1 81 System.out.println("最小三角剖分代价为:"+A[0][ps.length-1]); 82 } 83 84 public static void divide(int[][] B,int i,int j){ 85 if(B[i][j]!=0){ 86 System.out.println("Point:"+i+",Point:"+j+",Point:"+B[i][j]); 87 divide(B,i,B[i][j]); 88 divide(B,B[i][j],j); 89 } 90 } 91 92 //顶点序号i和j之间的距离 93 public static double dist(Point[] ps, int i,int j){ 94 double m1=Math.pow(ps[i].x-ps[j].x, 2); 95 double m2=Math.pow(ps[i].y-ps[j].y, 2); 96 return Math.sqrt(m1+m2); 97 } 98 99 } 100 101 class Point{ 102 public double x; 103 public double y; 104 public Point(double x,double y){ 105 this.x=x; 106 this.y=y; 107 } 108 }