**问题描述:**

给定某空间中(直线空间或平面空间)n个点,请找出它们中的最近点对。你需要完成下列任务:

1、随机产生或手工输入n个点的坐标。

2、输出最近的两个点的坐标。

3、算法尽可能效率高。

解决方案:

针对问题,主要包括两个方面的问题,一是在直线空间求最近点对,二是在平面空间求最近点对。具体解决办法如下:

(1)直线空间求最近点对问题

求最近点对如果直接用蛮力法,即有n个点,从第一个点开始依次算出两点直接的距离,进行大小比较,求出最小值,其时间效率为O(n^2)。那有没有效率更高一点的办法呢?结果当然是有的,那就是采用迭代法(时间效率为O(n*logn),先找出一组点中的中间点,使得在中间点左边的x坐标小于中间点x坐标,中间点右边的x坐标大于中间点x坐标,分成左右两组,用第一组左边组X最大值与右边组X最小值相减即得当前最短距离,在依次迭代,最后递归合并求出最终最短距离。

分治法方案具体代码如下:

package com.liuzhen.ex_two;public class ClosestPionts {//初始化一个随机数组public static int[] initializationArray(int n){int[] result = new int[n];for(int i = 0;i < n;i++)result[i] = (int)(Math.random()*1000); //采用随机函数随机生成1~1000之间的数return result;}//返回数组中最大值public static int getArrayMax(int a[] , int first , int end){int max = a[first];for(int i = first;i < end;i++){if(max < a[i])max = a[i];}return max;}//返回数组中最小值public static int getArrayMin(int a[] , int first , int end){int min = a[first];for(int i = first;i < end;i++){if(min > a[i])min = a[i];}return min;}//交换数组a[n]中两个数的值public static void swapArray(int a[] , int i , int j){int temp = a[i];a[i] = a[j];a[j] = temp;}//采用分治法将数组a[n]分成两组,满足a[n1]<m,a[n2]>m(其中n1+n2 = n)public static int divideArray(int a[],int first,int end){int max = getArrayMax(a,first,end);int min = getArrayMin(a,first,end);double m = (max + min)/2.0;//System.out.println("分治法算出中位数m:"+m);int i = first , j = end-1;//int a1 = 0;for( ;i+1 <= j;){while(a[i] < m && i+1 <= j)i++; while(a[j] > m && i+1 <= j)j--;//  a1++;//    System.out.println("第"+a1+"此交换时a[i] = "+a[i]+" i = "+i+"  a[j] = "+a[j]+" j = "+j);swapArray(a,i,j);   //a[i]大于m的值与a[j]小于m的值进行交换,但数组的位置不变}//System.out.println("分组后,返回的序号j值是:"+(j));return j;}//采用递归法合并最短距离值,返回最短距离的点public static int[] getMinDistancePoint(int a[] , int result[],int n ,int first , int end) {if(end-first <= 1){   //递归终止条件return result;}int j = divideArray(a,first,end);int minDistance = result[1] - result[0];  //最短距离两点之间的距离大小if(minDistance > getArrayMin(a,j,end)-getArrayMax(a,first,j)){result[0] = getArrayMax(a,first,j);   //最短距离两点中数值最小的点result[1] = getArrayMin(a,j,end);   //最短距离两点中数值最小的点} int result_one[] = getMinDistancePoint(a,result,2,first,j);   //递归int minDistance_one = result_one[1] - result_one[0]; int result_two[] = getMinDistancePoint(a,result,2,j,end);   //递归int minDistance_two = result_two[1] - result_two[0];if(minDistance > minDistance_one)result = result_one;if(minDistance > minDistance_two)result = result_two;return result;}public static void main(String[] args){int a[] = new int[10];int b[] = new int[2];b[0] = 0;b[1] = 100;a = initializationArray(15);String one_text = "";for(int i = 0;i < 15;i++){one_text += "直线随机点Point["+i+"] = "+a[i]+"\n";//System.out.print("数组a["+i+"] = "+a[i]+"\n");}int result[] = getMinDistancePoint(a,b,2,0,15);//System.out.println("result[0] = "+result[0]+"\n"+"result[1] = "+result[1]);one_text += "最短距离点对第1点result[0] = "+result[0]+"\n"+"最短距离点对第2点result[1] = "+result[1];System.out.print(one_text);}
}

结果为

(2)平面空间求最近点对问题

平面空间教直线空间求最近点对问题就变得更加复杂一点,在此就只讨论使用蛮力法求解平面空间求最近点对问题,如有对平面使用分治法求解感兴趣的同学请看本文末尾参考资料2。

蛮力法方案具体如下:

由于是在平面,点坐标表示为(x,y),在此先创建一个Point类(方便后续功能类实现):

package com.liuzhen.ex_two;public class Point {private int x;   //平面点中的x坐标private int y;   //平面点中的y坐标//未给类对象初始化时,默认点坐标为(0,0)public Point(){this.x = 0;this.y = 0;}public Point(int x,int y){this.x = x;this.y = y;}//给x赋值public void setX(int x){this.x = x;}//给y赋值public void setY(int y){this.y = y;}//返回xpublic int getX(){return x;}//返回ypublic int getY(){return y;}
}

蛮力法

package com.liuzhen.ex_two;public class ClosestPionts {//平面中求两点最短距离问题解法 //初始化一个平面中n个点,具体点的坐标值随机生成public static Point[] initializationPlaneArray(int n){Point result[] = new Point[n];for(int i = 0;i < n;i++){int x1 = (int)(Math.random()*50); //采用随机函数随机生成1~100之间的数int y1 =  (int)(Math.random()*50);result[i] = new Point(x1,y1);            }return result;}//蛮力法直接求平面中两点之间的最短距离,返回最短距离的两点坐标public static Point[] getMinDistancePlanePoint(Point a[],int n){Point result[] = new Point[2];double min = 10000;    //定义两点之间最短距离变量,初始化为10000for(int i = 0;i < n;i++){int x = a[i].getX();int y = a[i].getY();for(int j = i+1;j < n;j++){int x1 = a[j].getX();int y1 = a[j].getY();long minSquare = (x-x1)^2 + (y-y1)^2;   //利用数学中求两点之间距离公式,得到两点之间距离的平方double min1 = Math.sqrt(minSquare);    //求两点之间距离的中间变量if(min > min1){min = min1;                result[0] = new Point(x,y);result[1] = new Point(x1,y1);}}}return result;}public static void main(String[] args){String two_text = "";Point c[] = initializationPlaneArray(15);for(int i = 0;i < 15;i++){two_text += "Point["+i+"] = "+"("+c[i].getX()+","+c[i].getY()+")"+"\n";//System.out.println("c["+i+"] = "+"("+c[i].getX()+","+c[i].getY()+")");}//System.out.println(two_text);Point back[] = getMinDistancePlanePoint(c,15);for(int i = 0;i < 2;i++){two_text +=  "距离最短的两点第"+(i+1)+"个点坐标是:"+"("+back[i].getX()+","+back[i].getY()+")"+"\n";//System.out.println("距离最短的两点第"+(i+1)+"个点坐标是:"+"("+back[i].getX()+","+//back[i].getY()+")");}System.out.println(two_text);}}

结果为

Java实现最近点问题相关推荐

  1. Java实现算法导论中最近点对问题分治法

    最近点对问题:给定平面上的N个点,找出距离最近的两个点.分治法:              1 )如果数组长度(即点的个数,一般≤3)在一定范围内时直接求出最近点,蛮力求解,递归退出条件:       ...

  2. hdu1007最近点对问题(分冶java)

    题目链接 题意就是给若干点,求最近点对问题. 首先这题是我很久前看到的,我那时候用了o(n^2)因为数据量太大,计算太多超时.当时看了别人的分析就说分冶当时看代码太长也就没静下心看.前天翻了数据结构看 ...

  3. 根据经纬度求最近点的三种解法java实现

    文章目录 1. geoHash 2. kdTree算法求最近点 3.暴力法 4.利用elasticsearch或者lucene 1. geoHash 首先对经纬度点进行编码: 利用geoHash把经纬 ...

  4. 平面最近点对问题求解—基于Java语言

    平面最近点对问题求解-基于Java语言 1. 问题描述: 本问题来自<编程之美2.11-寻找最近点对>,文中给出了两种解法:暴力解法,分治解法.其中,暴力解法很简单,求出所有点之间的距离并 ...

  5. java算法《丢硬币、最近点对》

    用分治法解决如下问题: 已知给定n个硬币中有一个是假币,鉴别方式为假币重量比真币轻,请找出n个硬币中的这个假币.用分治策略设计算法解决此问题,并测试算法的正确性,要求输出假币所在的位置以及重量. 最近 ...

  6. JTS Java空间几何计算、距离、最近点、subLine等计算

    文章目录 前言 地理坐标系和投影坐标系 地理坐标系 投影坐标系 地图投影 墨卡托/Web墨卡托 常见坐标系 地理坐标系和投影坐标系互转 EPSG:3857和EPSG:4326 Java各坐标系之间的转 ...

  7. JTS Java空间几何计算、距离、最近点、subLine等 稳健的一比,持续更新中

    文章目录 前言 地理坐标系和投影坐标系 地理坐标系 投影坐标系 地图投影 墨卡托/Web墨卡托 常见坐标系 地理坐标系和投影坐标系互转 EPSG:3857和EPSG:4326 Java各坐标系之间的转 ...

  8. java快排算法解读,java 快排的思路与算法

    java 快排的思路与算法 有时候面试的时候的会问道Arrays.sort()是怎么实现的,我以前根本不知道是什么东西,最近点进去看了一下.直接吓傻, //看到这个时候还是比较淡定的,可怕的事情来了. ...

  9. Java 编程技巧之数据结构

    Photo @markusspiske 文 | 常意 导读 唐宋八大家之一欧阳修在<卖油翁>中写道: 翁取一葫芦置于地,以钱覆其口,徐以杓酌油沥之,自钱孔入,而钱不湿.因曰:"我 ...

最新文章

  1. MYSQL 连接数据库命令收藏
  2. python 报错 TypeError: type ‘types.GenericAlias‘ is not an acceptable base type
  3. python编写简单赌博游戏赏析及注意事项
  4. JMeter基础之组件的作用域与执行顺序
  5. DevOps 和敏捷开发的区别是什么?
  6. PDM系统的产品结构管理与版本控制
  7. OpenCV(三) 图像的读取和显示
  8. Java实现:学生管理系统
  9. 高通模式9008模式linux,高通芯片如何进入9008模式深度救砖
  10. cad解除块的快捷命令_CAD撤销上一步和恢復下一步的快捷键是什么?
  11. 在unti-app中使用阿里的iconfont图标
  12. QT学习笔记(六)——①进度条可拖动、点击②有暂停按钮 的视频播放器
  13. 【合规性检查方法-Fitness 2】基于Alignment的拟合度评估方法
  14. 360 os3.0 android7.1,360OS 3.0系统
  15. win8局域网访问其他计算机名,win8.1局域网找不到其他电脑怎么办
  16. android仿微信红包动画,Android仿微信打开红包动画(逐帧动画)
  17. [Spring] [最佳实践] 如何对 @Async 标记的异步方法进行单元测试
  18. 自认为最中肯的“北大”评价吧(转)
  19. 多元线性回归分析预测法概述
  20. golang命名规范

热门文章

  1. css grid布局中的minmax()函数的使用
  2. AI人工智能算法解析落地实践专栏列表
  3. 利用window的CLSID可以干的一些事情
  4. centos上升级node_如何升级nodejs到最新版本
  5. Jquery之瀑布流
  6. Java学习day096 并发(六)(线程安全的集合:高效的映射、集和队列、映射条目的原子更新、对并发散列映射的批操作、并发集视图、写数组的拷贝、并行数组算法、较早的线程安全集合)
  7. 【备忘】hive 调优
  8. 清华大学计算机系刘景财,2017年清华大学计算机系硕士录取名单
  9. Tasteless challenges hard WP
  10. 二元隐函数求二阶偏导_高数,隐函数求二阶偏导。f(x-y,yz)确定了z=(x,y),f具有二阶连续偏导数,求...