• Expm 3_2 寻找最邻近的点对


     

    【问题描述】

    p1=(x1,y1), p2=(x2,y2), … , pn=(xn,yn) 是平面上n个点构成的集合S,设计和实现找出集合S中距离最近点对的算法。

      每一个格子最多只能存在一个点,三行最多存在12个顶点,因此对于上图中的第(i=27)个顶点来说,最多只需要比较第27个顶点与之后的11个顶点,对于i之后或之前的11个顶点之外的顶点j,即|i-j|>=12,i与j之间的距离一定大于d,因为i和j已经相隔了至少两行。两个顶点若相隔大于等于两行或两列,则他们之间的距离一定大于等于d

      1 package org.xiu68.exp.exp3;
      2 
      3 import java.util.ArrayList;
      4 import java.util.List;
      5 import java.util.Random;
      6 
      7 public class Exp3_2 {
      8 
      9     //设p1=(x1,y1), p2=(x2,y2), … , pn=(xn,yn)
     10     //是平面上n个点构成的集合S,设计和实现找出集合S中距离最近点对的算法。
     11     public static void main(String[] args) {
     12         // TODO Auto-generated method stub
     13         for(int i=0;i<20;i++){
     14             System.out.println("***************************");
     15             List<Point> pointList=new ArrayList<>();
     16             for(int j=0;j<50;j++){
     17                 Point p=new Point(new Random().nextInt(100),new Random().nextInt(100));
     18                 pointList.add(p);
     19             }
     20             System.out.println(bruteforce(pointList));        //蛮力法
     21             System.out.println(closestPair(pointList));        //分治法
     22             
     23             System.out.println("****************************");
     24         }
     25     }
     26 
     27     
     28     
     29     //寻找最近点对
     30     public static double closestPair(List<Point> pointList){
     31         //对pointList中的点按横坐标和纵坐标进行升序排序
     32         
     33         List<Point> sortedListX=new ArrayList<>();    
     34         List<Point> sortedListY=new ArrayList<>();    
     35         
     36         //按横坐标对数组进行升序排序
     37         pointList.sort((Point a,Point b)->{
     38             if(a.getX()<b.getX())
     39                 return -1;
     40             else 
     41                 return 1;
     42         });
     43         sortedListX.addAll(pointList);
     44         
     45         //按纵坐标对数组进行升序排序
     46         pointList.sort((Point a,Point b)->{
     47             if(a.getY()<b.getY())
     48                 return -1;
     49             else 
     50                 return 1;
     51         });
     52         sortedListY.addAll(pointList);
     53         
     54 /*        for(int i=0;i<pointList.size();i++)
     55             System.out.println(sortedListX.get(i));
     56         System.out.println("*********************");
     57         for(int i=0;i<pointList.size();i++)
     58             System.out.println(sortedListY.get(i));
     59         
     60         System.out.println("*********************");
     61         System.out.println(divide(sortedListX,sortedListY));*/
     62         
     63         return divide(sortedListX,sortedListY);
     64         
     65     }
     66     
     67     /*
     68      * 原问题的分解
     69      * sortedListX:横坐标升序排序的数组
     70      * sortedListY:纵坐标升序排序的数组
     71      */
     72     public static double divide(List<Point> sortedListX,List<Point> sortedListY){
     73         if(sortedListX.size()==1)        //如果只有一个元素
     74             return Double.MAX_VALUE;
     75         else if(sortedListX.size()==2)    //如果只有两个元素
     76             return dist(sortedListX.get(0),sortedListX.get(1));
     77         
     78         else{                            //大于2个元素
     79             int mid=sortedListX.size()/2;                //在第mid个点处把点分成左右相等的两部分
     80             double L=sortedListX.get(mid).getX();    //把点分成左右相等的两部分的直线的横坐标,设这条直线为L
     81             
     82             //L左边的点的横坐标升序排序的数组
     83             List<Point> sortedListXL=sortedListX.subList(0, mid);    
     84             
     85             //L右边的点的横坐标升序排序的数组
     86             List<Point> sortedListXR=sortedListX.subList(mid, sortedListX.size());
     87             
     88             List<Point> sortedListYL=new ArrayList<>();        //L左边的点的纵坐标升序排序的数组
     89             List<Point> sortedListYR=new ArrayList<>();        //L右边的点的纵坐标升序排序的数组
     90             
     91             //求sortedListYL与sortedListYR
     92             for(int i=0;i<sortedListY.size();i++){
     93                 Point p=sortedListY.get(i);
     94                 if(sortedListY.get(i).getX()<L){
     95                     sortedListYL.add(p);
     96                 }else{
     97                     sortedListYR.add(p);
     98                 }
     99             }
    100             
    101             double dL=divide(sortedListXL,sortedListYL);    //L左边两个点之间的最短距离
    102             double dR=divide(sortedListXR,sortedListYR);    //L右边两个点之间的最短距离
    103             
    104             //比较L左边最短距离、L右边最短距离以及跨越L的顶点对之间的最短距离
    105             return conquer(sortedListY,L,Math.min(dL, dR));    
    106         }//else
    107     }
    108     
    109     //子问题解的合并
    110     public static double conquer(List<Point> sortedListY,double L,double d){
    111         //求在L-d以及L+d之间的顶点(2d-strip)
    112         List<Point> inside2DList=new ArrayList<>();
    113         for(int i=0;i<sortedListY.size();i++){
    114             Point p=sortedListY.get(i);
    115             if(p.getX()>L-d || p.getX()<L+d){
    116                 inside2DList.add(p);
    117             }
    118         }
    119         
    120         //求2d-strip之间顶点对的最短距离、与L左边和右边的最短距离比较,最小者为最终结果
    121         double minDistance=d;
    122         for(int i=0;i<inside2DList.size()-1;i++){
    123             //i只需与i之后的11个顶点比较,i与大于11个顶点之后的顶点的距离一定大于等于d
    124             for(int j=i+1;j<=i+11 && j<inside2DList.size();j++){
    125                 double temp=dist(inside2DList.get(i),inside2DList.get(j));
    126                 if(temp<minDistance)
    127                     minDistance=temp;
    128             }
    129         }
    130         return minDistance;
    131     }
    132     
    133     //计算两点之间的距离
    134     public static double dist(Point a,Point b){
    135         return Math.sqrt(Math.pow(a.getX()-b.getX(), 2)+Math.pow(a.getY()-b.getY(), 2));
    136     }
    137     
    138     //蛮力法
    139     public static double bruteforce(List<Point> pointList){
    140         double minDistance=Double.MAX_VALUE;
    141         //依次比较每个顶点对
    142         for(int i=0;i<pointList.size();i++){
    143             for(int j=i+1;j<pointList.size();j++){
    144                 double temp=dist(pointList.get(i),pointList.get(j));
    145                 if(temp<minDistance)
    146                     minDistance=temp;
    147             }
    148         }
    149         return minDistance;
    150     }
    151 }
    152 
    153 class Point{
    154     private double x;        //横坐标
    155     private double y;        //纵坐标
    156     
    157     public Point(int x,int y){
    158         this.x=x;
    159         this.y=y;
    160     }
    161 
    162     public double getX() {
    163         return x;
    164     }
    165 
    166     public void setX(double x) {
    167         this.x = x;
    168     }
    169 
    170     public double getY() {
    171         return y;
    172     }
    173 
    174     public void setY(double y) {
    175         this.y = y;
    176     }
    177 
    178     public String toString(){
    179         return x+","+y;
    180     }
    181 }
    View Code
  • 相关阅读:
    随笔导航
    利用CORDIC算法计算三角函数
    粒子群算法求一元函数最值问题
    基于粒子群算法的分组背包MATLAB实现
    遇到过的MATLAB函数小总结
    FFT原理及C++与MATLAB混合编程详细介绍
    DPSK通信系统的FPGA实现
    矩阵QR分解的MATLAB与C++实现
    矩阵LU分解的MATLAB与C++实现
    两种频率调制(FM)方法的MATLAB实现
  • 原文地址:https://www.cnblogs.com/xiu68/p/7988640.html
Copyright © 2020-2023  润新知