凸边形最优三角剖分问题

来源:互联网 发布:软件测试英文工作报告 编辑:程序博客网 时间:2024/06/05 15:44

参考博客:草滩小恪的博客园   网址: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]);
        
    }

}








1 0
原创粉丝点击