参考博客:草滩小恪的博客园 网址:http://www.cnblogs.com/acm1314/p/4574606.html
凸多边形的三角剖分:凸多边形分割成互不相交的三角形的弦的集合。
最优剖分:给定凸多边形P,以及定义在由多边形的边和弦组成的三角形上的权函数w。要求确定该凸多边形的三角剖分,使得该三角剖分中诸三角形上权之和为最小。
若凸(n+1)边形P={V0,V1,V2,,,,Vn}的最优剖分包含三角形V0VkVn,0<k<n,则T的权为三角形V0VkVn的权,多边形{V0,V1,V2...Vk}和{Vk,Vk+1,...Vn}的权之和。
设:t[i][j],0<i<j<=n为凸多边形{Vi-1,Vi,,,,Vj}的最优三角剖分权函数值,则包括三角形Vi-1VkVj,和子多边形{Vi-1,Vi,,,Vk}的权,和{Vk,Vk+1,,,Vj}权之和。
故:
t[i][j]=min{t[i][k]+t[k+1][j]+w(Vi-1VkVj)},其中,i<=k<j
i=j时,t[i][j]=0
故凸多边形为:
t[1][n]=min{t[1][k]+t[k+1][n]+w(V0VkVn)} ,其中1<=k<n
Java代码:
package example;
//最优剖分:给定凸多边形P,以及定义在由多边形的边
//和弦组成的三角形上的权函数w。要求确定该凸多边形的三角剖分,
//使得该三角剖分中诸三角形上权之和为最小。
public class GoodTriangle {
// 若凸(n+1)边形P={V0,V1,V2,,,,Vn}的最优剖分包含三角形V0VkVn,0<k<n,
// 则T的权为三角形V0VkVn的权,多边形{V0,V1,V2...Vk}和{Vk,Vk+1,...Vn}的权之和。
/*
* 设:t[i][j],0<i<j<=n为凸多边形{Vi-1,Vi,,,,Vj}的最优三角剖分权函数值,则包括三角形Vi-1VkVj,和子多边形{Vi-
* 1,Vi,,,Vk}的权,和{Vk,Vk+1,,,Vj}权之和。 故:
* t[i][j]=min{t[i][k]+t[k+1][j]+w(Vi-1VkVj)},其中,i<=k<j
* t[i][j]=0,其中,i=j(当i=j时,即为Vi-1Vi此为边,故值为0)
*
* 实例1:凸四边形:P4={V0,V1,V2,V3},求最优剖分,权为W(ViVkVj)=Vi*Vk*Vj,求乘积和最小。 设值为1,2,3,4
* 第一种情况:1*2*3+1*3*4=18,第二种情况为:1*2*4+2*3*4=32,故最优值为18
*
* 实例2:凸三角形,值为1*2*3=6
*
* 实例3:二边和一点的均为0
*/
//凸(n+1)边形P,即{V0,V1,V2,,,,Vn}的最优权值为
//t[1][n]=min{t[1][k]+t[k+1][n]+w(V0VkVn)},1<=k<n
/*
* 输入n为凸(n+1)边形,t为最优值;s为记录的最优路径,v为顶点值
* */
public static int getMostGoodTriangle(int n,int[][] t,int[][] s,int[] V){
//t[i][j]为{Vi-1,Vi,,,Vj}的最优值,1<=i<j,故
for(int i=1;i<=n;i++) //i=j时为0
t[i][i]=0;
//如果这种形式的话,那么t[i][j],如t[1][n],此时无法知道t[i][j]的值,因为此时i!=j
/*
for(int i=1;i<n;i++){
for(int j=i+1;j<=n;j++){
}
}
*/
//可以求的值为t[1][2],t[2][3],t[3][4],,t[n-1][n],相差为1,之后
//t[1][3],t[2][4],,t[n-2][n],差为2,一直直到差为n-1,为t[1][n]
for(int r=2;r<=n;r++){ //差值 //如果r=1,i=1,j=1,距离小 ,故r>1 //当r=n时,此时i为1,j为1+n-1=n,此时,正好t[1][n]
for(int i=1;i<=n-r+1;i++){ //起始值
int j=i+r-1;
//t[i][j]=min{t[i][k]+t[k+1][j]+w(Vi-1VkVj)},其中,i<=k<j,
//当r=2时,j=i+1,t[i][j]为t[i][i+1]差1,此时t[i+1][j]=0,正好得到第一轮的值
//r=3时,j=i+2差为2个,相当于1个的差值
t[i][j]=t[i+1][j]+getWeight(i-1,i,j,V);
s[i][j] = i;
for(int k=i+1;k<j;k++){ //
int value=t[i][k]+t[k+1][j]+getWeight(i-1,k,j,V);
if(value<t[i][j]){
t[i][j]=value;
s[i][j]=k;
}
}
}
}
return 0;
}
/*
* 得到三个点的值,得到三角形的权重(三个顶点的乘积)
* 输入为三角形的点Vi,Vk,Vj
* 输出为三角形的权重
* */
public static int getWeight(int i,int k,int j,int[] V){
return V[i]*V[k]*V[j];
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] V={1,2,3,4,5,6};//此时n为5,凸6边形
int n=5;
int[][] t=new int[n+1][n+1];
int[][] s=new int[n+1][n+1];
getMostGoodTriangle(n,t,s,V);
System.out.println("最优值="+t[1][5]);
}
}