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