分治——最近点对

Posted bear_ge

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分治——最近点对相关的知识,希望对你有一定的参考价值。

代码有点长

仍在奋斗,提升技能 (? ??_??)? (*?????)?

public class pointNode {      //定义坐标结构
    double x;
    double y;
}

public class PArray {          //定义个坐标数组类
         pointNode []pN;
}

public class distance {     //两坐标所构成的边
    
    pointNode p1;
    pointNode p2;
    double dis;
}


*
 * 定义一个方法类,里面包含实现该算法的一些方法;
 * 
 */

public  class staticMethod {                   
    static double min(distance d1,distance d2){      // 返回两条边长度最小的那条边
        return d1.dis>d2.dis?d2.dis:d1.dis;
    }
    static double Distance(pointNode p1,pointNode p2){    //求两点间的距离
        
        return Math.sqrt((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y));
    }
    static pointNode[] quickSort(pointNode pN[],char ch){    //用快速排序对x轴或y轴排序 ,ch表示x或y轴
        double d[]=new double[pN.length];
        
        if(ch==‘x‘){                          
            for(int i=0;i<d.length;i++){
                d[i]=pN[i].x;
            }
        }
        else{
            for(int i=0;i<d.length;i++){
                d[i]=pN[i].y;
            }
        }
        int t=d.length-1;
        
            pN=quickSort(0,d.length-1,pN,d);
        
        return pN;
        
    }
    private static pointNode[] quickSort(int start,int end,pointNode pN[],double d[]){      //  快排
        
        
        int left=start+1,right=end;
        
        while(left<right){
            while((d[right]>d[start])){right--;}
                if(right>left){ d[left]=d[right];pN[left++]=pN[right];}
            while((d[left]<d[start])){left++;}
                if(right>left){ d[right]=d[left];pN[right++]=pN[left];}
                
                d[left]=d[start];
                pN[left]=pN[start];
        
        }
        return pN;
    }    
}


package 最近点对;
public class theShortestDistance {
    public static void main(String a[]){
        PArray p=new PArray();     
        p.pN=new pointNode[6];         //输入点对坐标                
        for(int i=0;i<6;i++){
            p.pN[i]=new pointNode();
        }
        
        p.pN[0].x=1;
        p.pN[0].y=1;
        
        p.pN[1].x=2;
        p.pN[1].y=2;
        
        p.pN[2].x=4;
        p.pN[2].y=4;
        
        p.pN[3].x=7;
        p.pN[3].y=3;
        
        p.pN[4].x=9;
        p.pN[4].y=1;
        
        p.pN[5].x=10;
        p.pN[5].y=1;      //结束输入
        
        distance dis=new distance();   //申请一条边
        tsd(0,5,p,dis);   
        System.out.println("p1.x "+dis.p1.x+" p1.y "+dis.p1.y+" p2.x "+dis.p2.x+" p2.y "+dis.p2.y+" dis "+dis.dis);
    }
     
    public static void tsd(int start ,int end ,PArray p,distance dis){     
        if(start<end){
            if(end-start==1){
                dis.p1=p.pN[start];
                dis.p2=p.pN[end];
                dis.dis=staticMethod.Distance(dis.p1,dis.p2);
            }
            else{
                distance d1,d2;
                d1=new distance();
                d2=new distance();
                
                tsd(start,(start+end)/2,p,d1);
                tsd((start+end)/2,end,p,d2);
                
                merge(start,end,p,d1.dis<d2.dis?d1:d2,dis);
                d1=d2=null;
                    
            }
        }
        
    }
    public static void merge(int start,int end ,PArray p,distance dis1,distance dis){
        if(end-start==2){
            dis.p1=p.pN[start];
            dis.p2=p.pN[end];
            dis.dis=staticMethod.Distance(dis.p1, dis.p2);
            
            if(dis.dis>dis1.dis){
                dis.p1=dis1.p1;
                dis.p2=dis1.p2;
                dis.dis=dis1.dis;
            }
            return ;
        }
        PArray p1=new PArray();
        p1.pN=new pointNode[end-start+1];
        int middle=(start+end)/2;
        int j=0;
        for(int i=0;i<end-start+1;i++){
            if(Math.abs(p.pN[i].x-p.pN[middle].x) <= dis1.dis/2){
                p1.pN[j++]=p.pN[i];
            }
        }
        PArray p2=new PArray();
        p2.pN=new pointNode[j];
        for(int i=0;i<j;i++){
            p2.pN[i]=p1.pN[i];
        }
        
        p1.pN=staticMethod.quickSort(p2.pN,‘y‘);  //对y坐标排序;
        j=0;
        for(int i=0;i<j;i++){                    //筛选
            if(Math.abs(p1.pN[i].y-p1.pN[j/2].y)<=dis1.dis/2){
                p2.pN[j++]=p1.pN[i];
            }
        }
        
        tsd(0,j-1,p,dis);
        if(dis.p1==null){
            dis.p1=dis1.p1;
            dis.p2=dis1.p2;
            dis.dis=dis1.dis;
        }
        
        p1=p2=null;
    }
}
 

 

以上是关于分治——最近点对的主要内容,如果未能解决你的问题,请参考以下文章

分治 -- 平面最近点对

poj3714 Raid(分治求平面最近点对)

分治&暴力求解最近点对问题 + 时间性能量化分析

分治法二(平面最近点对)

Quoit Design(最近点对+分治)

平面最近点对(分治)